link several Popen commands with pipes
I think you want to instantiate two separate Popen objects here, one for 'ls' and the other for 'sed'. You'll want to pass the first Popen object's stdout
attribute as the stdin
argument to the 2nd Popen object.
Example:
p1 = subprocess.Popen('ls ...', stdout=subprocess.PIPE)p2 = subprocess.Popen('sed ...', stdin=p1.stdout, stdout=subprocess.PIPE)print p2.communicate()
You can keep chaining this way if you have more commands:
p3 = subprocess.Popen('prog', stdin=p2.stdout, ...)
See the subprocess documentation for more info on how to work with subprocesses.
I've made a little function to help with the piping, hope it helps. It will chain Popens as needed.
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
"""Why don't you use shell"""def output_shell(line): try: shell_command = Popen(line, stdout=PIPE, stderr=PIPE, shell=True) except OSError: return None except ValueError: return None (output, err) = shell_command.communicate() shell_command.wait() if shell_command.returncode != 0: print "Shell command failed to execute" return None return str(output)