天天看点

【Python】执行外部命令并获取输出执行外部命令并获取输出

执行外部命令并获取输出

subprocess

模块运行用户生成新的进程,并连接它们的输入、输出、错误管道,并且获取它们的返回码。

1. 执行一个外部命令的

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
	)
           

常用参数:

  1. args

    ,要执行的指令。
  2. 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
>>>
           
  1. timeout

    ,timeout 参数将被传递给

    Popen.communicate()

    。如果发生超时,子进程将被杀死并等待。

    TimeoutExpired

    异常将在子进程中断后被抛出。
  2. input

    input

    参数将被传递给

    Popen.communicate()

    以及子进程的

    stdin

    。 如果使用此参数,它必须是一个字节序列。 如果指定了

    encoding

    errors

    或者将

    text

    设置为

    True

    ,那么也可以是一个字符串。 当使用此参数时,在创建内部

    Popen

    对象时将自动带上

    stdin=PIPE

    ,并且不能再手动指定

    stdin

    参数。
  3. check

    ,如果

    check

    设为

    True

    , 并且进程以非零状态码退出, 一个

    CalledProcessError

    异常将被抛出. 这个异常的属性将设置为参数, 退出码, 以及标准输出和标准错误, 如果被捕获到.
  4. 如果

    encoding

    或者

    error

    被指定, 或者

    text

    被设为

    True

    , 标准输入, 标准输出和标准错误的文件对象将通过指定的

    encoding

    errors

    以文本模式打开, 否则以默认的

    io.TextIOWrapper

    打开.

    universal_newline

    参数等同于

    text

    并且提供了向后兼容性. 默认情况下, 文件对象是以二进制模式打开的。

2.

subprocess

较早的 API 函数

现在多数情况可以使用

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'