一, commands 模块
1, 介绍
当我们使用 Python 进行编码的时候, 但是又想运行一些 shell 命令, 去创建文件夹, 移动文件等等操作时, 我们可以使用一些 Python 库去执行 shell 命令.
commands 模块就是其中的一个可执行 shell 命令的库, commands 模块是 python 的内置模块, 共有三个函数:
getstatus(file): 返回执行 ls -ld file 命令的结果( -ld 代表的是仅列出指定目录的详细信息).
getoutput(cmd): 执行 cmd 命令, 并返回输出的内容, 返回结果为 str.
getstatusoutput(cmd): 执行 cmd 命令, 并返回执行的状态 (status) 和输出的内容(output),status 代表的 shell 命令的返回状态, 如果成功的话是 0,output 是 shell 的返回的结果.
注意:
commands 从 2.6 版开始不推荐使用: 该模块已在 Python 3 中删除. 推荐使用 subprocess 模块(等下再介绍).
在 3.x 版本中, getstatus()方法被移除, getoutput()和 getstatusoutput()被放到了 subprocess 模块中.
2,getstatus(file)
返回执行 ls -ld file 命令的结果( -ld 代表的是仅列出指定目录的详细信息).
- # -*- coding: utf-8 -*-
- import commands
- status = commands.getstatus("/opt") # 即执行了: ls -ld /opt
- print status
- # 结果
- drwxr-xr-x. 9 root root 4096 2019/11/11 16:49:40 /opt
- 3,getoutput(cmd)
执行 cmd 命令, 并返回输出的内容, 返回结果为 str.
- # -*- coding: utf-8 -*-
- import commands
- output = commands.getoutput("ls -l /opt")
- print output
- # 结果
总用量 28
- drwx--x--x 4 root root 4096 2019/11/11 16:49:40 containerd
- drwxr-xr-x 13 root root 4096 2019/01/15 14:48:15 nginx1.12
- drwxrwxr-x 7 500 500 4096 2019/01/14 10:30:05 node-v8.6.0-Linux-x64
- drwxr-xr-x 7 root root 4096 2019/09/17 09:31:24 Projects
- drwxr-xr-x 6 root root 4096 2019/01/10 19:17:30 python36
- drwxrwxr-x 8 root root 4096 2019/09/16 20:00:52 Redis-4.0.10
- drwxr-xr-x 6 root root 4096 2019/01/16 17:47:34 Ruby
- 4,getstatusoutput(cmd)
执行 cmd 命令, 并返回执行的状态 (status) 和输出的内容(output),status 代表的 shell 命令的返回状态, 如果成功的话是 0,output 是 shell 的返回的结果.
- # -*- coding: utf-8 -*-
- import commands
- status, output = commands.getstatusoutput("ls -l /opt")
- print "status: %s" % status
- print "output: %s" % output
- # 结果
- status: 0
output: 总用量 28
- drwx--x--x 4 root root 4096 2019/11/11 16:49:40 containerd
- drwxr-xr-x 13 root root 4096 2019/01/15 14:48:15 nginx1.12
- drwxrwxr-x 7 500 500 4096 2019/01/14 10:30:05 node-v8.6.0-Linux-x64
- drwxr-xr-x 7 root root 4096 2019/09/17 09:31:24 Projects
- drwxr-xr-x 6 root root 4096 2019/01/10 19:17:30 python36
- drwxrwxr-x 8 root root 4096 2019/09/16 20:00:52 Redis-4.0.10
- drwxr-xr-x 6 root root 4096 2019/01/16 17:47:34 Ruby
二, subprocess 模块
1, 介绍
subprocess 模块允许你启动一个新的进程, 连接输入 / 输出 / 错误的管道, 获得子进程的返回码. 这个模块目标是代替一些老的模块, 比如 os.system 和 os.spawn.
subprocess 模块中的常用函数
函数 | 描述 |
---|---|
subprocess.getoutput(cmd) | 接收字符串格式的命令,执行命令并返回执行结果,其功能类似于 os.popen(cmd).read()和 commands.getoutput(cmd)。 |
subprocess.getstatusoutput(cmd) | 执行 cmd 命令,返回一个元组(命令执行状态, 命令执行结果输出),其功能类似于 commands.getstatusoutput()。 |
subprocess.call() | 执行指定的命令,返回命令执行状态,其功能类似于 os.system(cmd)。 |
subprocess.check_call() | Python 2.5 中新增的函数。 执行指定的命令,如果执行成功则返回状态码,否则抛出异常。其功能等价于 subprocess.run(..., check=True)。 |
subprocess.check_output() | Python 2.7 中新增的的函数。执行指定的命令,如果执行状态码为 0 则返回命令执行结果,否则抛出异常。 |
subprocess.run() | Python 3.5 中新增的函数。执行指定的命令,等待命令执行完成后返回一个包含执行结果的 CompletedProcess 类的实例。 |
2,getoutput,getstatusoutput
上面我们说了, commands 在 3.x 版本中, getstatus()方法被移除, getoutput()和 getstatusoutput()被放到了 subprocess 模块中.
因此 subprocess 中的 getoutput,getstatusoutput 用法与 commands 的用法一模一样.
- # -*- coding: utf-8 -*-
- import subprocess
- output = subprocess.getoutput("pwd")
- print("output1: %s" % output)
- status, output = subprocess.getstatusoutput("pwd")
- print("status2: %s" % status)
- print("output2: %s" % output)
- # 结果
- output1: /tmp
- status2: 0
- output2: /tmp
- 3,subprocess.call()
执行命令, 返回状态码(命令正常执行返回 0, 其他状态码都是错误状态码)
subprocess.call(cmd, shell=False) 当 shell=False 的时候(默认),cmd 为一个列表, 当 shell=True 的时候, cmd 为一个字符串, 例如:
- # -*- coding:utf-8 -*-
- import subprocess
- try:
- # shell=False
- ret1 = subprocess.call(["ls", "-l", "/opt"], shell=False)
- print("result1: %s" % ret1)
- # shell=True
- ret2 = subprocess.call("lxxs -l /tmp", shell=True) # 当命令是错误的时候, 返回的状态码就不是 0 了
- print("result2: %s" % ret2)
- except Exception as e:
- print(e)
- # 结果
总用量 28
- drwx--x--x 4 root root 4096 2019/11/11 16:49:40 containerd
- drwxr-xr-x 13 root root 4096 2019/01/15 14:48:15 nginx1.12
- drwxrwxr-x 7 500 500 4096 2019/01/14 10:30:05 node-v8.6.0-Linux-x64
- drwxr-xr-x 7 root root 4096 2019/09/17 09:31:24 Projects
- drwxr-xr-x 6 root root 4096 2019/01/10 19:17:30 python36
- drwxrwxr-x 8 root root 4096 2019/09/16 20:00:52 Redis-4.0.10
- drwxr-xr-x 6 root root 4096 2019/01/16 17:47:34 Ruby
- result1: 0
/bin/sh: lxxs: 未找到命令
- result2: 127
- 4,subprocess.check_call()
执行命令, 如果执行成功则返回状态码 0, 否则抛异常(subprocess.CalledProcessError).
其实 check_call 基本和 call 功能一样, 只是增加了返回状态码校验, 如果执行状态码是 0, 则返回 0, 否则抛出异常
- # -*- coding:utf-8 -*-
- import subprocess
- try:
- ret = subprocess.check_call("ls -l /opt", shell=True)
- print("result: %s" % ret)
- except subprocess.CalledProcessError as e:
- print(e)
- 5,subprocess.check_output()
执行命令, 如果执行成功则返回执行结果, 否则抛异常
- # -*- coding:utf-8 -*-
- import subprocess
- try:
- ret = subprocess.check_output("ls -l /opt", shell=True)
- print("result: %s" % ret)
- except subprocess.CalledProcessError as e:
- print(e)
- # 结果
- result: b'\xe6\x80\xbb\xe7\x94\xa8\xe9\x87\x8f 28\ndrwx--x--x 4 root root 4096 2019/11/11 16:49:40 containerd\ndrwxr-xr-x 13 root root 4096 2019/01/15 14:48:15 nginx1.12\ndrwxrwxr-x 7 500 500 4096 2019/01/14 10:30:05 node-v8.6.0-linux-x64\ndrwxr-xr-x 7 root root 4096 2019/09/17 09:31:24 Projects\ndrwxr-xr-x 6 root root 4096 2019/01/10 19:17:30 python36\ndrwxrwxr-x 8 root root 4096 2019/09/16 20:00:52 redis-4.0.10\ndrwxr-xr-x 6 root root 4096 2019/01/16 17:47:34 ruby\n'
6,call,check_call,check_output 的区别
根据上面的结果, 我们可知:
ret1 = subprocess.call(cmd):ret1 是 cmd 命令执行后的状态码, cmd 执行的结果会在终端显示出来, 也就是说如果不需要判断命令的执行结果的状态码, 直接 subprocess.call(cmd)即可, 不需要用一个变量去接收状态码.
ret2 = subprocess.check_call(cmd): 跟 call 一样的, 只是如果状态码是不是 0, 即命令执行失败的时候会抛出异常.
ret3 = subprocess.check_output(cmd): call 和 check_call 的 ret 是 cmd 命令的状态码, cmd 的执行结果是在终端显示的, 而 check_output 的 cmd 执行结果不会显示在终端, 而是保存在 ret 中.
python 之 commands 和 subprocess 入门介绍(可执行 shell 命令的模块)
来源: http://www.bubuko.com/infodetail-3360562.html