《python标准库》--subprocess <一、运行外部命令>
作用:创建附加进程,并与之通信。如果一个程序需要生产或利用文本,这个模块尤其有帮助,因为这个API支持通过新进程的标准输入和输出通道来回传递数据。
subprocess模块提供了一种一致的方法来创建和处理附加进程。与标准库中的其他模块相比,它提供了一个更高级的接口,用以替换os.system()、os.spawnv()、os和popen2模块中的popen()函数,以及commands()。
subprocess模块定义了一个类Popen,还定义了使用这个类的一些包装器函数。Popen的构造函数根据一些参数建立新进程,使父进程可以通过管道与之通信。相对于它替换的其他模块和函数,subprocess能提供其全部功能,甚至更多。对于所有情况,这个API用法都一致,很多需要开销的额外步骤(如关闭额外的文件描述符,以及确保管道关闭)都已“内置”,而不需要由应用代码单独处理。
要运行一个外部命令,但不采用os.system()的方式与之交互,可以使用call()函数。命令行参数作为一个字符串列表传入,这样就无须对引号或者其他可能由shell解释的特殊字符转义。
1 >>> import subprocess 2 >>> subprocess.call(['ls','-l']) 3 data 4 test.py 5 0 6 >>>
将shell参数设置为true值会使subprocess创建一个中间shell进程,由这个进程运行命令。默认情况下会直接运行命令。
>>> import subprocess >>> subprocess.call('ls -l',shell=True) 总用量 52 drwxr-xr-x 2 root root 4096 8月 9 22:29 data -rw-r--r-- 1 root root 469 8月 7 22:52 test.py 0 >>>
call()的返回值是程序的退出码。调用者要负责解释这个返回值来检测错误。check_call()函数的工作类似于call(),只不过除了检查退出码外,如果指示发生了一个错误,则会产生一个CalledProcesssError异常。
1 >>> import subprocess 2 >>> try: 3 ... subprocess.check_call(['false']) 4 ... except subprocess.CalledProcessError as err: 5 ... print 'ERROR:',err 6 ... 7 ERROR: Command '['false']' returned non-zero exit status 1 8 >>>
对于call()启动的进程,其标准输入和输出通道会绑定到父进程的输入和输出。这说明调用程序无法捕获命令的输出。可以使用check_output()捕获输出,以备以后处理。ls -l命令会成功运行,所以它打印到标准输出到文本会被捕获并返回。
1 >>> import subprocess 2 >>> output = subprocess.check_output(['ls','-l']) 3 >>> print 'Have %d bytes in output' % len(output) 4 Have 822 bytes in output 5 >>> print output 6 总用量 56 7 drwxr-xr-x 2 root root 4096 8月 9 22:29 data 8 -rw-r--r-- 1 root root 469 8月 7 22:52 test.py 9 10 >>>
下一个例子在一个子shell中运行一系列命令。在命令返回一个错误码并退出之前,消息会发送到标准输出和标准错误输出。发送到标准错误输出的消息会打印到控制台,不过发送到标准输出的消息会隐藏。
1 >>> import subprocess 2 >>> try: 3 ... output = subprocess.check_output( 4 ... 'echo to stdout; echo to stderr 1>&2; exit 1', 5 ... shell=True,
#stderr=subprocess.STDOUT 6 ... ) 7 ... except subprocess.CalledProcessError as err: 8 ... print 'ERROR:',err 9 ... else: 10 ... print 'Have %d bytes in output' % len(output) 11 ... print output 12 ... 13 to stderr #将check_output()中的stderr参数设置为常量STDOUT时,这句不会被输出。 14 ERROR: Command 'echo to stdout; echo to stderr 1>&2; exit 1' returned non-zero exit status 1 15 >>>