在 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.stdouts,以便可以正确接收SIGPIPEs:

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 调用管道命令的主要内容,如果未能解决你的问题,请参考以下文章

Python os.popen() 方法

popen() 可以制作像 pipe() + fork() 这样的双向管道吗?

Python 使用OS模块调用 cmd

带有标准输入的 subprocess.Popen.communicate() 的管道损坏

os.system和os.popen函数

python遍历目录就是这么简单