Index: Doc/library/subprocess.rst =================================================================== --- Doc/library/subprocess.rst (revision 65655) +++ Doc/library/subprocess.rst (working copy) @@ -148,7 +148,18 @@ .. versionadded:: 2.5 +.. function:: pipe(*commands, **kw) + Run a chain of commands, returns the output of the last one. + + Arguments are a list of command line arguments, an optional keyword "stderr" + can be used to capture stdandard error as well. Example:: + + chain(["dmesg"], ["grep", "hda"]) + + .. versionadded:: 2.6 + + Exceptions ^^^^^^^^^^ Index: Lib/test/test_subprocess.py =================================================================== --- Lib/test/test_subprocess.py (revision 65655) +++ Lib/test/test_subprocess.py (working copy) @@ -82,6 +82,14 @@ env=newenv) self.assertEqual(rc, 1) + def test_pipe(self): + cmd1 = [sys.executable, "-c", "print 'MOO'"] + cmd2 = [sys.executable, "-c", + "import sys; print sys.stdin.read().replace('M', 'B')"] + + out = subprocess.pipe(cmd1, cmd2).strip() + self.assertEqual(out, "BOO") + def test_stdin_none(self): # .stdin is None when not redirected p = subprocess.Popen([sys.executable, "-c", 'print "banana"'], Index: Lib/subprocess.py =================================================================== --- Lib/subprocess.py (revision 65655) +++ Lib/subprocess.py (working copy) @@ -127,6 +127,14 @@ check_call(["ls", "-l"]) +pipe(*commands, **kw): + Run a chain of commands, reutns the output of the last one. + + Arguments are a list of command line arguments, an optional keyword "stderr" + can be used to capture stdandard error as well. Example: + + chain(["dmesg"], ["grep", "hda"]) + Exceptions ---------- Exceptions raised in the child process, before the new program has @@ -224,11 +232,8 @@ ------------------------- output=`dmesg | grep hda` ==> -p1 = Popen(["dmesg"], stdout=PIPE) -p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE) -output = p2.communicate()[0] +output = pipe(["dmesg"], ["grep", "hda"]) - Replacing os.system() --------------------- sts = os.system("mycmd" + " myarg") @@ -462,7 +467,22 @@ raise CalledProcessError(retcode, cmd) return retcode +def pipe(*commands, **kw): + """Run a chain of commands, returns the output of the last one. + Arguments are a list of command line arguments, an optional keyword "stderr" + can be used to capture stdandard error as well. Example: + + chain(["dmesg"], ["grep", "hda"]) + """ + stderr = STDOUT if kw.get("stderr", False) else None + pipe = None + for cmdline in commands: + stdin = pipe.stdout if pipe else None + pipe = Popen(cmdline, stdin=stdin, stdout=PIPE, stderr=stderr) + + return pipe.communicate()[0] + def list2cmdline(seq): """ Translate a sequence of arguments into a command line