aboutsummaryrefslogtreecommitdiffstats
path: root/libbe/util/subproc.py
diff options
context:
space:
mode:
Diffstat (limited to 'libbe/util/subproc.py')
-rw-r--r--libbe/util/subproc.py44
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