用管道链接几个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]

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


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]

你能告诉我我做错了吗?


谢谢


饮歌长啸
浏览 372回答 3
3回答

LEATH

我认为您想在此处实例化两个单独的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()如果您有更多命令,则可以保持链接的方式:p3 = subprocess.Popen('prog', stdin=p2.stdout, ...)请参阅子流程文档以获取有关如何使用子流程的更多信息。

长风秋雁

我已经做了一些功能来帮助管道,希望对您有所帮助。它将根据需要链接Popens。from subprocess import Popen, PIPEimport shlexdef 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_codeoutput, 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 hereelse:  # Be happy :D  print output

米琪卡哇伊

shlex 仅根据shell规则拆分空间,但不处理管道。但是,它应该以这种方式工作:import subprocessimport shlexsp_ls = subprocess.Popen(shlex.split(r'ls -l'), stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE)sp_sed = subprocess.Popen(shlex.split(r'sed "s/a/b/g"'), stdin = sp_ls.stdout, stdout = subprocess.PIPE, stderr = subprocess.PIPE)sp_ls.stdin.close() # makes it similiar to /dev/nulloutput = sp_ls.communicate()[0] # which makes you ignore any errors.print output根据help(subprocess)的Replacing shell pipe line-------------------------output=`dmesg | grep hda`==>p1 = Popen(["dmesg"], stdout=PIPE)p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)output = p2.communicate()[0]高温超导
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python