在Python中用Popen调用管道命令

时间:2013-01-28 18:28:17

标签: python unix subprocess

调用包含多个管道的命令到Popen的正确方法是什么,以便可以读取其输出?我试过了:

Popen(shlex.split("mycmd arg1 | mysecondcmd - | thirdcmd -", stdout=PIPE)")

但我不相信shlex.split就在这里。什么是正确的语法?

2 个答案:

答案 0 :(得分:6)

您有几个选择 - 您可以传递shell=True

Popen('command1 | command2 | command3',shell=True)

或者,您可以将其分解成一堆Popen次呼叫,将他们的标准输出连接到下一个Popen的标准输出,如documentation中所示。

答案 1 :(得分:2)

使用sh module,管道成为功能组合:

import sh
output = sh.thirdcmd(sh.mysecondcmd(sh.mycmd("arg1")))

如果您想在没有shell = True的子流程中执行此操作,则会显示example in the docs,其中显示了如何使用subprocess.Popen编写shell管道。请注意,您应该关闭proc.stdout以便正确接收SIGPIPE

import subprocess
proc1 = subprocess.Popen(shlex.split('mycmd arg1'), stdout = subprocess.PIPE)
proc2 = subprocess.Popen(shlex.split('mysecondcmd'), stdin = proc1.PIPE,
                         stdout = subprocess.PIPE)
proc3 = subprocess.Popen(shlex.split('thirdcmd'), stdin = proc2.PIPE,
                         stdout = subprocess.PIPE)

# Allow proc1 to receive a SIGPIPE if proc2 exits.
proc1.stdout.close()
# Allow proc2 to receive a SIGPIPE if proc3 exits.
proc2.stdout.close()
out, err = proc3.communicate()

这可能看起来比使用shell = True要多得多。您可能希望避免shell = True的原因是因为it can be a security risk(向下翻到“警告”框),尤其是在您运行由(可能是恶意的)用户提供的命令时。