invoking pipe command with Popen in Python

What is the correct way to invoke a command containing multiple pipes to Popen so that its output can be read? I tried:

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

But I don't believe shlex.split is right here. What's the correct syntax?


You have a few options -- You can pass shell=True :

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

Or, you can break it up into a bunch of Popen calls hooking their stdout to the next Popen's stdin as demonstrated in the documentation.


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.stdout s so that SIGPIPE s 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.

链接地址: http://www.djcxy.com/p/77088.html

上一篇: subprocess.Popen管道如何在Python中工作?

下一篇: 在Python中用Popen调用pipe命令