10.1 subprocess:创建附加进程
subprocess模块提供了3个API来处理进程。run()函数是Python 3.5中新增的,作为一个高层API,其用于运行进程并收集它的输出(可选)。函数call(),check_call()和check_output()是从Python2沿袭来的原高层API。这些函数仍受到支持,并在现有的程序中广泛使用。类Popen是一个用于建立其他API的底层API,对更复杂的进程交互很有用。Popen的构造函数利用参数建立新进程,使父进程可以通过管道与之通信。它可以替换其他一些模块和函数,并能提供所替换的这些模块和函数的全部功能,甚至还更多。在所有情况下这个API的用法都是一致的,很多存在开销的额外步骤(如关闭额外的文件描述符,以及确保管道关闭)都已经"内置"在这个API中,不需要由应用代码单独处理。
subprocess模块是为了替换os.system(),os.spawnv(),os和popen2模块中不同形式的popen()函数,以及commands模块。为了更容易地比较subprocess和其他这些模块,这一节中的很多例子会重新创建os和popen2中使用的例子。
10.1.1 运行外部命令
要运行一个外部命令,但不采用os.system()的方式与之交互,可以使用run()函数。
import subprocess
completed = subprocess.run(['ls','-1'])
print('returncode:',completed.returncode)
命令行参数作为一个字符串列表传入,这样就无需对引号或其他可能由shell解释的特殊字符转义。run()返回一个CompletedProcess实例,它包含进程的有关信息,如退出码和输出。
运行结果:
将shell参数设置为true值会使subprocess创建一个中间shell进程,由这个进程运行命令。默认情况下会直接运行命令。
import subprocess
completed = subprocess.run('echo $HOME',shell=True)
print('returncode:',completed.returncode)
使用一个中间shell意味着运行命令之前会先处理命令串中的变量、glob模式以及其他特殊shell特性。
说明:如果使用run()而没有传入check=True,这等价于使用call(),值返回进程的退出码。
运行结果: