diff options
Diffstat (limited to 'libbe/util/subproc.py')
-rw-r--r-- | libbe/util/subproc.py | 44 |
1 files changed, 29 insertions, 15 deletions
diff --git a/libbe/util/subproc.py b/libbe/util/subproc.py index b10f84a..fde5af5 100644 --- a/libbe/util/subproc.py +++ b/libbe/util/subproc.py @@ -1,4 +1,5 @@ -# Copyright (C) 2009-2011 W. Trevor King <wking@drexel.edu> +# Copyright (C) 2009-2011 Chris Ball <cjb@laptop.org> +# W. Trevor King <wking@drexel.edu> # # This file is part of Bugs Everywhere. # @@ -21,6 +22,7 @@ Functions for running external commands in subprocesses. from subprocess import Popen, PIPE import sys +import types import libbe from encoding import get_encoding @@ -45,7 +47,8 @@ class CommandError(Exception): self.stderr = stderr def invoke(args, stdin=None, stdout=PIPE, stderr=PIPE, expect=(0,), - cwd=None, unicode_output=True, verbose=False, encoding=None): + cwd=None, shell=None, unicode_output=True, verbose=False, + encoding=None): """ expect should be a tuple of allowed exit codes. cwd should be the directory from which the command will be executed. When @@ -54,18 +57,29 @@ def invoke(args, stdin=None, stdout=PIPE, stderr=PIPE, expect=(0,), """ if cwd == None: cwd = '.' + if isinstance(shell, types.StringTypes): + list_args = ' '.split(args) # sloppy, but just for logging + str_args = args + else: + list_args = args + str_args = ' '.join(args) # sloppy, but just for logging if verbose == True: - print >> sys.stderr, '%s$ %s' % (cwd, ' '.join(args)) + print >> sys.stderr, '%s$ %s' % (cwd, str_args) try : if _POSIX: - q = Popen(args, stdin=PIPE, stdout=stdout, stderr=stderr, cwd=cwd) + if shell is None: + shell = False + q = Popen(args, stdin=PIPE, stdout=stdout, stderr=stderr, + shell=shell, cwd=cwd) else: assert _MSWINDOWS==True, 'invalid platform' + if shell is None: + shell = True # win32 don't have os.execvp() so have to run command in a shell q = Popen(args, stdin=PIPE, stdout=stdout, stderr=stderr, - shell=True, cwd=cwd) + shell=shell, cwd=cwd) except OSError, e: - raise CommandError(args, status=e.args[0], stderr=e) + raise CommandError(list_args, status=e.args[0], stderr=e) stdout,stderr = q.communicate(input=stdin) status = q.wait() if unicode_output == True: @@ -78,18 +92,18 @@ def invoke(args, stdin=None, stdout=PIPE, stderr=PIPE, expect=(0,), if verbose == True: print >> sys.stderr, '%d\n%s%s' % (status, stdout, stderr) if status not in expect: - raise CommandError(args, status, stdout, stderr) + raise CommandError(list_args, status, stdout, stderr) return status, stdout, stderr class Pipe (object): - """ - Simple interface for executing POSIX-style pipes based on the - subprocess module. The only complication is the adaptation of - subprocess.Popen._comminucate to listen to the stderrs of all - processes involved in the pipe, as well as the terminal process' - stdout. There are two implementations of Pipe._communicate, one - for MS Windows, and one for POSIX systems. The MS Windows - implementation is currently untested. + """Simple interface for executing POSIX-style pipes. + + Based on the `subprocess` module. The only complication is the + adaptation of `subprocess.Popen._communicate` to listen to the + stderrs of all processes involved in the pipe, as well as the + terminal process' stdout. There are two implementations of + `Pipe._communicate`, one for MS Windows, and one for POSIX + systems. The MS Windows implementation is currently untested. >>> p = Pipe([['find', '/etc/'], ['grep', '^/etc/ssh$']]) >>> p.stdout |