在 Python 中使用 Popen 调用管道命令
Posted
技术标签:
【中文标题】在 Python 中使用 Popen 调用管道命令【英文标题】:invoking pipe command with Popen in Python 【发布时间】:2013-01-12 04:23:09 【问题描述】:调用包含多个管道的命令到Popen
以便读取其输出的正确方法是什么?我试过了:
Popen(shlex.split("mycmd arg1 | mysecondcmd - | thirdcmd -", stdout=PIPE)")
但我不相信shlex.split
就在这里。正确的语法是什么?
【问题讨论】:
一方面,您将stdout=PIPE
作为参数传递给shlex.split
,而不是Popen
构造函数。另一方面,您有奇数个"
字符;大概是最后一个无关紧要的。另外,如果你想使用 shell 功能,你必须通过shell=True
。 (您通常不希望生成一个 shell 来将命令连接在一起,但如果您愿意,也可以。)
link several Popen commands with pipes的可能重复
【参考方案1】:
你有几个选择——你可以通过shell=True
:
Popen('command1 | command2 | command3',shell=True)
或者,您可以将其分解为一组 Popen
调用,将它们的标准输出连接到下一个 Popen 的标准输入,如 documentation 中所示。
【讨论】:
【参考方案2】:使用sh module,管道成为函数组合:
import sh
output = sh.thirdcmd(sh.mysecondcmd(sh.mycmd("arg1")))
如果你想在没有shell = True
的情况下使用子进程,有一个example in the docs 显示如何使用subprocess.Popen
编写shell 管道。请注意,您应该关闭proc.stdout
s,以便可以正确接收SIGPIPE
s:
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(向下翻到“警告”框),尤其是在您运行由(可能是恶意的)用户提供的命令时。
【讨论】:
以上是关于在 Python 中使用 Popen 调用管道命令的主要内容,如果未能解决你的问题,请参考以下文章
popen() 可以制作像 pipe() + fork() 这样的双向管道吗?