【问题标题】:invoking pipe command with Popen in Python在 Python 中使用 Popen 调用管道命令
【发布时间】:2023-03-24 11:21:02
【问题描述】:

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

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

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

【问题讨论】:

  • 一方面,您将stdout=PIPE 作为参数传递给shlex.split,而不是Popen 构造函数。另一方面,您有奇数个" 字符;大概是最后一个无关紧要的。另外,如果你想使用 shell 功能,你必须通过shell=True。 (您通常不希望生成一个 shell 来将命令连接在一起,但如果您愿意,也可以。)

标签: python unix subprocess


【解决方案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(向下翻到“警告”框),尤其是在您运行由(可能是恶意的)用户提供的命令时。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-15
      • 2011-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-05
      相关资源
      最近更新 更多