diff options
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/commands.py | 77 | ||||
-rw-r--r-- | Lib/subprocess.py | 76 | ||||
-rwxr-xr-x | Lib/test/regrtest.py | 3 | ||||
-rw-r--r-- | Lib/test/test___all__.py | 1 | ||||
-rw-r--r-- | Lib/test/test_commands.py | 47 | ||||
-rw-r--r-- | Lib/test/test_subprocess.py | 34 |
6 files changed, 103 insertions, 135 deletions
diff --git a/Lib/commands.py b/Lib/commands.py deleted file mode 100644 index ee4db85..0000000 --- a/Lib/commands.py +++ /dev/null @@ -1,77 +0,0 @@ -"""Execute shell commands via os.popen() and return status, output. - -Interface summary: - - import commands - - outtext = commands.getoutput(cmd) - (exitstatus, outtext) = commands.getstatusoutput(cmd) - outtext = commands.getstatus(file) # returns output of "ls -ld file" - -A trailing newline is removed from the output string. - -Encapsulates the basic operation: - - pipe = os.popen('{ ' + cmd + '; } 2>&1', 'r') - text = pipe.read() - sts = pipe.close() - - [Note: it would be nice to add functions to interpret the exit status.] -""" - -__all__ = ["getstatusoutput", "getoutput"] - -# Module 'commands' -# -# Various tools for executing commands and looking at their output and status. -# -# NB This only works (and is only relevant) for UNIX. - - -# Get the output from a shell command into a string. -# The exit status is ignored; a trailing newline is stripped. -# Assume the command will work with '{ ... ; } 2>&1' around it.. -# -def getoutput(cmd): - """Return output (stdout or stderr) of executing cmd in a shell.""" - return getstatusoutput(cmd)[1] - - -# Ditto but preserving the exit status. -# Returns a pair (sts, output) -# -def getstatusoutput(cmd): - """Return (status, output) of executing cmd in a shell.""" - import os - pipe = os.popen('{ ' + cmd + '; } 2>&1', 'r') - text = pipe.read() - sts = pipe.close() - if sts is None: sts = 0 - if text[-1:] == '\n': text = text[:-1] - return sts, text - - -# Make command argument from directory and pathname (prefix space, add quotes). -# -def mk2arg(head, x): - import os - return mkarg(os.path.join(head, x)) - - -# Make a shell command argument from a string. -# Return a string beginning with a space followed by a shell-quoted -# version of the argument. -# Two strategies: enclose in single quotes if it contains none; -# otherwise, enclose in double quotes and prefix quotable characters -# with backslash. -# -def mkarg(x): - if '\'' not in x: - return ' \'' + x + '\'' - s = ' "' - for c in x: - if c in '\\$"`': - s = s + '\\' - s = s + c - s = s + '"' - return s diff --git a/Lib/subprocess.py b/Lib/subprocess.py index d39eb19..ba4fac0 100644 --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -17,7 +17,6 @@ intends to replace several other, older modules and functions, like: os.system os.spawn* -commands.* Information about how the subprocess module can be used to replace these modules and functions can be found below. @@ -105,7 +104,7 @@ appearance of the main window and priority for the new process. (Windows only) -This module also defines two shortcut functions: +This module also defines four shortcut functions: call(*popenargs, **kwargs): Run command with arguments. Wait for command to complete, then @@ -125,6 +124,34 @@ check_call(*popenargs, **kwargs): check_call(["ls", "-l"]) +getstatusoutput(cmd): + Return (status, output) of executing cmd in a shell. + + Execute the string 'cmd' in a shell with os.popen() and return a 2-tuple + (status, output). cmd is actually run as '{ cmd ; } 2>&1', so that the + returned output will contain output or error messages. A trailing newline + is stripped from the output. The exit status for the command can be + interpreted according to the rules for the C function wait(). Example: + + >>> import subprocess + >>> subprocess.getstatusoutput('ls /bin/ls') + (0, '/bin/ls') + >>> subprocess.getstatusoutput('cat /bin/junk') + (256, 'cat: /bin/junk: No such file or directory') + >>> subprocess.getstatusoutput('/bin/junk') + (256, 'sh: /bin/junk: not found') + +getoutput(cmd): + Return output (stdout or stderr) of executing cmd in a shell. + + Like getstatusoutput(), except the exit status is ignored and the return + value is a string containing the command's output. Example: + + >>> import subprocess + >>> subprocess.getoutput('ls /bin/ls') + '/bin/ls' + + Exceptions ---------- Exceptions raised in the child process, before the new program has @@ -336,7 +363,8 @@ else: import fcntl import pickle -__all__ = ["Popen", "PIPE", "STDOUT", "call", "check_call", "CalledProcessError"] +__all__ = ["Popen", "PIPE", "STDOUT", "call", "check_call", "getstatusoutput", + "getoutput", "CalledProcessError"] try: MAXFD = os.sysconf("SC_OPEN_MAX") @@ -458,6 +486,48 @@ def list2cmdline(seq): return ''.join(result) +# Various tools for executing commands and looking at their output and status. +# +# NB This only works (and is only relevant) for UNIX. + +def getstatusoutput(cmd): + """Return (status, output) of executing cmd in a shell. + + Execute the string 'cmd' in a shell with os.popen() and return a 2-tuple + (status, output). cmd is actually run as '{ cmd ; } 2>&1', so that the + returned output will contain output or error messages. A trailing newline + is stripped from the output. The exit status for the command can be + interpreted according to the rules for the C function wait(). Example: + + >>> import subprocess + >>> subprocess.getstatusoutput('ls /bin/ls') + (0, '/bin/ls') + >>> subprocess.getstatusoutput('cat /bin/junk') + (256, 'cat: /bin/junk: No such file or directory') + >>> subprocess.getstatusoutput('/bin/junk') + (256, 'sh: /bin/junk: not found') + """ + pipe = os.popen('{ ' + cmd + '; } 2>&1', 'r') + text = pipe.read() + sts = pipe.close() + if sts is None: sts = 0 + if text[-1:] == '\n': text = text[:-1] + return sts, text + + +def getoutput(cmd): + """Return output (stdout or stderr) of executing cmd in a shell. + + Like getstatusoutput(), except the exit status is ignored and the return + value is a string containing the command's output. Example: + + >>> import subprocess + >>> subprocess.getoutput('ls /bin/ls') + '/bin/ls' + """ + return getstatusoutput(cmd)[1] + + class Popen(object): def __init__(self, args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py index 41772c6..032cac0 100755 --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -868,7 +868,6 @@ _expectations = { """ test__locale test_bsddb3 - test_commands test_crypt test_curses test_dbm @@ -910,7 +909,6 @@ _expectations = { test_bsddb test_bsddb3 test_bz2 - test_commands test_crypt test_curses test_dbm @@ -1060,7 +1058,6 @@ _expectations = { """ test_audioop test_bsddb3 - test_commands test_curses test_dl test_epoll diff --git a/Lib/test/test___all__.py b/Lib/test/test___all__.py index 89395be..e33c54a 100644 --- a/Lib/test/test___all__.py +++ b/Lib/test/test___all__.py @@ -50,7 +50,6 @@ class AllTest(unittest.TestCase): self.check_all("codecs") self.check_all("codeop") self.check_all("colorsys") - self.check_all("commands") self.check_all("compileall") self.check_all("copy") self.check_all("copyreg") diff --git a/Lib/test/test_commands.py b/Lib/test/test_commands.py deleted file mode 100644 index b4e48ce..0000000 --- a/Lib/test/test_commands.py +++ /dev/null @@ -1,47 +0,0 @@ -''' - Tests for commands module - Nick Mathewson -''' -import unittest -import os, tempfile, re - -from test.support import TestSkipped, run_unittest, reap_children -from commands import * - -# The module says: -# "NB This only works (and is only relevant) for UNIX." -# -# Actually, getoutput should work on any platform with an os.popen, but -# I'll take the comment as given, and skip this suite. - -if os.name != 'posix': - raise TestSkipped('Not posix; skipping test_commands') - - -class CommandTests(unittest.TestCase): - - def test_getoutput(self): - self.assertEquals(getoutput('echo xyzzy'), 'xyzzy') - self.assertEquals(getstatusoutput('echo xyzzy'), (0, 'xyzzy')) - - # we use mkdtemp in the next line to create an empty directory - # under our exclusive control; from that, we can invent a pathname - # that we _know_ won't exist. This is guaranteed to fail. - dir = None - try: - dir = tempfile.mkdtemp() - name = os.path.join(dir, "foo") - - status, output = getstatusoutput('cat ' + name) - self.assertNotEquals(status, 0) - finally: - if dir is not None: - os.rmdir(dir) - - -def test_main(): - run_unittest(CommandTests) - reap_children() - -if __name__ == "__main__": - test_main() diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py index 3f877f2..c9a3e1b 100644 --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -702,10 +702,36 @@ class ProcessTestCase(unittest.TestCase): p.terminate() self.assertNotEqual(p.wait(), 0) +class CommandTests(unittest.TestCase): +# The module says: +# "NB This only works (and is only relevant) for UNIX." +# +# Actually, getoutput should work on any platform with an os.popen, but +# I'll take the comment as given, and skip this suite. + if os.name == 'posix': + + def test_getoutput(self): + self.assertEquals(subprocess.getoutput('echo xyzzy'), 'xyzzy') + self.assertEquals(subprocess.getstatusoutput('echo xyzzy'), + (0, 'xyzzy')) + + # we use mkdtemp in the next line to create an empty directory + # under our exclusive control; from that, we can invent a pathname + # that we _know_ won't exist. This is guaranteed to fail. + dir = None + try: + dir = tempfile.mkdtemp() + name = os.path.join(dir, "foo") + + status, output = subprocess.getstatusoutput('cat ' + name) + self.assertNotEquals(status, 0) + finally: + if dir is not None: + os.rmdir(dir) + def test_main(): - support.run_unittest(ProcessTestCase) - if hasattr(support, "reap_children"): - support.reap_children() + support.run_unittest(ProcessTestCase, CommandTests) + support.reap_children() if __name__ == "__main__": - unittest.main() # XXX test_main() + test_main() |