用管道链接几个Popen命令

26 python command subprocess pipe popen

我知道如何使用cmd = subprocess.Popen然后subprocess.communicate运行命令.大多数时候我使用shlex.split标记化的字符串作为Popen的'argv'参数."ls -l"的示例:

import subprocess
import shlex
print subprocess.Popen(shlex.split(r'ls -l'), stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE).communicate()[0]
Run Code Online (Sandbox Code Playgroud)

但是,管道似乎不起作用...例如,以下示例返回注意:

import subprocess
import shlex
print subprocess.Popen(shlex.split(r'ls -l | sed "s/a/b/g"'), stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE).communicate()[0]
Run Code Online (Sandbox Code Playgroud)

你能告诉我我做错了吗?

谢谢

Ale*_*ith 42

我想你想在这里实例化两个独立的Popen对象,一个用于'ls'而另一个用于'sed'.您将要将第一个Popen对象的stdout属性作为stdin参数传递给第二个Popen对象.

例:

p1 = subprocess.Popen('ls ...', stdout=subprocess.PIPE)
p2 = subprocess.Popen('sed ...', stdin=p1.stdout, stdout=subprocess.PIPE)
print p2.communicate()
Run Code Online (Sandbox Code Playgroud)

如果你有更多的命令,你可以保持这种方式链接:

p3 = subprocess.Popen('prog', stdin=p2.stdout, ...)
Run Code Online (Sandbox Code Playgroud)

有关如何使用子进程的更多信息,请参阅子进程文档.

  • @Leonid你应该只需要在最后一个进程上调用一次**,因为你已经生成了所有这些并将它们链接在一起.所以,如果你有进程`p1`,`p2`,....,`pn`,最后只需调用`pn.communicate()`. (7认同)

her*_*vnc 6

我做了一个小功能来帮助管道,希望它有所帮助。它将根据需要链接 Popens。

from subprocess import Popen, PIPE
import shlex

def run(cmd):
  """Runs the given command locally and returns the output, err and exit_code."""
  if "|" in cmd:    
    cmd_parts = cmd.split('|')
  else:
    cmd_parts = []
    cmd_parts.append(cmd)
  i = 0
  p = {}
  for cmd_part in cmd_parts:
    cmd_part = cmd_part.strip()
    if i == 0:
      p[i]=Popen(shlex.split(cmd_part),stdin=None, stdout=PIPE, stderr=PIPE)
    else:
      p[i]=Popen(shlex.split(cmd_part),stdin=p[i-1].stdout, stdout=PIPE, stderr=PIPE)
    i = i +1
  (output, err) = p[i-1].communicate()
  exit_code = p[0].wait()

  return str(output), str(err), exit_code

output, err, exit_code = run("ls -lha /var/log | grep syslog | grep gz")

if exit_code != 0:
  print "Output:"
  print output
  print "Error:"
  print err
  # Handle error here
else:
  # Be happy :D
  print output
Run Code Online (Sandbox Code Playgroud)