diff options
author | Georg Brandl <georg@python.org> | 2008-12-07 15:30:06 (GMT) |
---|---|---|
committer | Georg Brandl <georg@python.org> | 2008-12-07 15:30:06 (GMT) |
commit | f9734076cf12444fb1b5e4296993bf6df3b1e7f2 (patch) | |
tree | 1a07422957dfa4cafe9868efd8965ab9abd6cf86 /Lib/subprocess.py | |
parent | 2080ea5f4b7ab8bd9ab0385c7ac925731d78405e (diff) | |
download | cpython-f9734076cf12444fb1b5e4296993bf6df3b1e7f2.zip cpython-f9734076cf12444fb1b5e4296993bf6df3b1e7f2.tar.gz cpython-f9734076cf12444fb1b5e4296993bf6df3b1e7f2.tar.bz2 |
Merged revisions 67511,67536-67537,67543 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r67511 | vinay.sajip | 2008-12-04 00:22:58 +0100 (Thu, 04 Dec 2008) | 1 line
Issue #4384: Added logging integration with warnings module using captureWarnings(). This change includes a NullHandler which does nothing; it will be of use to library developers who want to avoid the "No handlers could be found for logger XXX" message which can appear if the library user doesn't configure logging.
........
r67536 | gregory.p.smith | 2008-12-04 21:21:09 +0100 (Thu, 04 Dec 2008) | 3 lines
Adds a subprocess.check_call_output() function to return the output from a
process on success or raise an exception on error.
........
r67537 | vinay.sajip | 2008-12-04 21:32:18 +0100 (Thu, 04 Dec 2008) | 1 line
Took Nick Coghlan's advice about importing warnings globally in logging, to avoid the possibility of race conditions: "This could deadlock if a thread spawned as a side effect of importing a module happens to trigger a warning. warnings is pulled into sys.modules as part of the interpreter startup - having a global 'import warnings' shouldn't have any real effect on logging's import time."
........
r67543 | gregory.p.smith | 2008-12-05 03:27:01 +0100 (Fri, 05 Dec 2008) | 2 lines
rename the new check_call_output to check_output. its less ugly.
........
Diffstat (limited to 'Lib/subprocess.py')
-rw-r--r-- | Lib/subprocess.py | 71 |
1 files changed, 59 insertions, 12 deletions
diff --git a/Lib/subprocess.py b/Lib/subprocess.py index ac92185..b47ebb8 100644 --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -104,7 +104,7 @@ appearance of the main window and priority for the new process. (Windows only) -This module also defines four shortcut functions: +This module also defines some shortcut functions: call(*popenargs, **kwargs): Run command with arguments. Wait for command to complete, then @@ -151,6 +151,17 @@ getoutput(cmd): >>> subprocess.getoutput('ls /bin/ls') '/bin/ls' +check_output(*popenargs, **kwargs): + Run command with arguments and return its output as a byte string. + + If the exit code was non-zero it raises a CalledProcessError. The + CalledProcessError object will have the return code in the returncode + attribute and output in the output attribute. + + The arguments are the same as for the Popen constructor. Example: + + output = subprocess.check_output(["ls", "-l", "/dev/null"]) + Exceptions ---------- @@ -166,8 +177,8 @@ should prepare for OSErrors. A ValueError will be raised if Popen is called with invalid arguments. -check_call() will raise CalledProcessError, if the called process -returns a non-zero return code. +check_call() and check_output() will raise CalledProcessError, if the +called process returns a non-zero return code. Security @@ -321,12 +332,15 @@ import signal # Exception classes used by this module. class CalledProcessError(Exception): - """This exception is raised when a process run by check_call() returns - a non-zero exit status. The exit status will be stored in the - returncode attribute.""" - def __init__(self, returncode, cmd): + """This exception is raised when a process run by check_call() or + check_output() returns a non-zero exit status. + The exit status will be stored in the returncode attribute; + check_output() will also store the output in the output attribute. + """ + def __init__(self, returncode, cmd, output=None): self.returncode = returncode self.cmd = cmd + self.output = output def __str__(self): return "Command '%s' returned non-zero exit status %d" % (self.cmd, self.returncode) @@ -364,7 +378,7 @@ else: import pickle __all__ = ["Popen", "PIPE", "STDOUT", "call", "check_call", "getstatusoutput", - "getoutput", "CalledProcessError"] + "getoutput", "check_output", "CalledProcessError"] try: MAXFD = os.sysconf("SC_OPEN_MAX") @@ -410,12 +424,45 @@ def check_call(*popenargs, **kwargs): check_call(["ls", "-l"]) """ retcode = call(*popenargs, **kwargs) - cmd = kwargs.get("args") - if cmd is None: - cmd = popenargs[0] if retcode: + cmd = kwargs.get("args") + if cmd is None: + cmd = popenargs[0] raise CalledProcessError(retcode, cmd) - return retcode + return 0 + + +def check_output(*popenargs, **kwargs): + """Run command with arguments and return its output as a byte string. + + If the exit code was non-zero it raises a CalledProcessError. The + CalledProcessError object will have the return code in the returncode + attribute and output in the output attribute. + + The arguments are the same as for the Popen constructor. Example: + + >>> check_output(["ls", "-l", "/dev/null"]) + 'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n' + + The stdout argument is not allowed as it is used internally. + To capture standard error in the result, use stderr=subprocess.STDOUT. + + >>> check_output(["/bin/sh", "-c", + "ls -l non_existant_file ; exit 0"], + stderr=subprocess.STDOUT) + 'ls: non_existant_file: No such file or directory\n' + """ + if 'stdout' in kwargs: + raise ValueError('stdout argument not allowed, it will be overridden.') + process = Popen(*popenargs, stdout=PIPE, **kwargs) + output, unused_err = process.communicate() + retcode = process.poll() + if retcode: + cmd = kwargs.get("args") + if cmd is None: + cmd = popenargs[0] + raise CalledProcessError(retcode, cmd, output=output) + return output def list2cmdline(seq): |