Python 模块 subprocess 派生新进程

Python 使用模块 subproces,生成新的进程并与之通信。

在 Python 2中,提供了 call(),check_call() 和 check_output()函数生成新进程的 API,他们也被带到了 Python 3。在 Python 3 中,新增了高级函数 run(),能够生成新进程并收集输出。

Popen 提供了低级别的 API,可以接收参数,父进程能够和子进程通过管道(Pipe)通信,它的接口 API 和高级的接口 API 保持一致,并且内部能够保证资源得到清理,例如自动关闭管道和文件描述符。

模块 subprocess 是用来替代旧的 os 模块函数,例如 os.system(),os.spawnv()。虽然 Windows 和 Unix 的底层进程模型是不一样的,但是接口 API 保持了一致,代码在多个平台不需要做太多的改动。

运行外部命令

使用 run() 函数运行外部的命令。

执行:

run() 函数的第一个参数是一个字符串列表,这样可以避免被 shell 解析特殊的字符。返回一个 CompletedProcess 实例,包含输出的信息或者退出状态。

使用属性 shell 设置为 True,会让 subprocess 生成一个新 shell 进程,然后再运行命令,此时第一个参数需要传递一个字符串。

执行:

call() 函数返回子进程的退出状态,相当于不传给 run() 参数 check=True

错误处理

设置属性 check 为 True,如果命令执行发生错误,会触发异常 CalledProcessError。

执行:

当给 run() 属性 check 设置为 True,相当于调用 check_call() 函数

捕获输出

上例中,执行 run() 函数,默认都把子进程的输出打印了,这是因为子进程的输入输出通道和父进程的一致。为了捕获输出或者错误信息,需要传递属性 stdout 或者 stderr,设置为 subprocess.PIPE。

执行:

当调用 run() 时,check=True 而且 stdout=PIPE ,相当于调用 check_output() 函数

为了捕获错误消息,我们可以把标准错误重定向到标准输出,设置属性 stderr 为 STDOUT。

执行:

上例中,使用 shell 命令输出两个字符串,一个是标准输出,另一个把标准输出重定向到标准错误。因为设置了属性 stderr,最终两个字符串都返回了。

抑制输出

设置 stdout 为 DEVNULL 抑制输出数据,下面的例子抑制了标准输出流和标准错误流。

执行:

使用 Popen

实例化 Popen, 并且设置 stdout 为 PIPE,调用 communicate() 方法捕获输出。

执行:

设置参数 stdin 为 PIPE,然后调用 communicate() 方法可以向子进程传递数据。

执行:

同时设置 stdin 和 stdout 为 PIPE,能够和子进程双向读取和写入数据。

执行:

通过设置 stdout 和 stderr,同时捕获输出和错误。

执行:

发表评论
留言与评论(共有 0 条评论)
   
验证码:

相关文章

推荐文章

'); })();