0

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

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

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

4

2 回答 2

6

你有几个选择——你可以通过shell=True

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

或者,您可以将其分解为一组Popen调用,将它们的标准输出连接到下一个 Popen 的标准输入,如文档中所示。

于 2013-01-28T18:31:07.100 回答
2

Using the sh module, pipes become function composition:

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

If you want to do it with subprocess without shell = True, there is an example in the docs which shows how to write shell pipelines using subprocess.Popen. Note that you are supposed to close the proc.stdouts so that SIGPIPEs can be received properly:

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()

This might look like a lot more work than using shell = True. The reason why you might want to avoid shell = True is because it can be a security risk (page down to the "Warning" box), especially if you are running a command supplied by a (potentially malicious) user.

于 2013-01-28T18:46:35.327 回答