执行外部命令并获取输出
subprocess
模块运行用户生成新的进程,并连接它们的输入、输出、错误管道,并且获取它们的返回码。
1. 执行一个外部命令的 subprocess.run()
函数
subprocess.run()
可以使用
subprocess
模块的
subprocess.check_output()
函数来调用子进程。
subprocess.run()
函数将运行
args
中描述的指令,指令完成后,返回一个
CompletedProcess
实例。
subprocess.run(
args,
stdin=None, stdout=None, stderr=None,
capture_output=False,
hell=False, cwd=None,
timeout=None,
check=False,
input=None,
encoding=None, errors=None, text=None,
env=None,
universal_newlines=None, **other_popen_kwargs
)
常用参数:
-
,要执行的指令。args
-
capture_output, stdin, stdout, stderr
- 如果
设为capture_output
,True
和stdout
将会被捕获。内置的stderr
对象将自动用Popen
和stdout=subprocess.PIPE
创建。stderr=subprocess.PIPE
-
和stdout
参数不应当与stderr
同时提供。如果你希望捕获并将两个流合并在一起,使用capture_output
和stdout=subprocess.PIPE
来代替stderr=subprocess.STDOUT
。capture_output
- 如果
>>> a = subprocess.run(["ls", "-l", "/dev/null"], capture_output=True)
>>> a
CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0, stdout=b'crw-rw-rw- 1 root root 1, 3 Jun 25 00:52 /dev/null\n', stderr=b'')
>>> a.stdout
b'crw-rw-rw- 1 root root 1, 3 Jun 25 00:52 /dev/null\n'
>>> a.stderr
b''
>>>
>>>
>>> a = subprocess.run(["ls", "-ol", "/dev/null"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
>>> a.stdout
b'crw-rw-rw- 1 root 1, 3 Jun 25 00:52 /dev/null\n'
>>> a.stderr
>>>
-
,timeout 参数将被传递给timeout
。如果发生超时,子进程将被杀死并等待。Popen.communicate()
异常将在子进程中断后被抛出。TimeoutExpired
-
,input
参数将被传递给input
以及子进程的Popen.communicate()
。 如果使用此参数,它必须是一个字节序列。 如果指定了stdin
或encoding
或者将errors
设置为text
,那么也可以是一个字符串。 当使用此参数时,在创建内部True
对象时将自动带上Popen
,并且不能再手动指定stdin=PIPE
参数。stdin
-
,如果check
设为check
, 并且进程以非零状态码退出, 一个True
异常将被抛出. 这个异常的属性将设置为参数, 退出码, 以及标准输出和标准错误, 如果被捕获到.CalledProcessError
- 如果
或者encoding
被指定, 或者error
被设为text
, 标准输入, 标准输出和标准错误的文件对象将通过指定的True
和encoding
以文本模式打开, 否则以默认的errors
打开.io.TextIOWrapper
参数等同于universal_newline
并且提供了向后兼容性. 默认情况下, 文件对象是以二进制模式打开的。text
2. subprocess
较早的 API 函数
subprocess
现在多数情况可以使用
run()
函数来完成,在
run()
函数之前常使用下面的这些函数。
-
函数subprocess.call()
subprocess.call(
args, *,
stdin=None,
stdout=None,
stderr=None,
shell=False,
cwd=None,
timeout=None,
**other_popen_kwargs
)
运行
args
所描述的命令。等待命令完成,然后返回
returncode
属性。
>>> a = subprocess.call(['ls', '-l'], stderr=subprocess.STDOUT)
-rwxrw-r-- 1 zzz zzz 69 May 12 12:28 test1.sh
-rwxrw-r-- 1 zzz zzz 88 May 12 12:40 test2.sh
-rwxrw-r-- 1 zzz zzz 91 May 12 12:45 test3.sh
>>> a
0
>>>
-
函数subprocess.check_call()
subprocess.check_call(
args, *,
stdin=None,
stdout=None,
stderr=None,
shell=False,
cwd=None,
timeout=None,
**other_popen_kwargs
)
执行
args
所描述的命令。等待命令完成。如果返回的状态码为0,则返回;否则,抛出
CalledProcessError
。
CalledProcessError
对象中有
returncode
属性的返回码。
-
函数subprocess.check_output()
subprocess.check_output(
args, *,
stdin=None,
stdout=None,
stderr=None,
shell=False,
cwd=None,
encoding=None,
errors=None,
universal_newlines=None,
timeout=None,
**other_popen_kwargs
)
附带参数运行命令并返回其输出。如果返回码非零则会引发
CalledProcessError
。
CalledProcessError
对象将在
returncode
属性中保存返回码并在 output 属性中保存所有输出。
>>> subprocess.check_output(
... "ls non_existent_file; exit 0",
... stderr=subprocess.STDOUT,
... shell=True)
'ls: non_existent_file: No such file or directory\n'