X-Git-Url: https://scripts.mit.edu/gitweb/wizard.git/blobdiff_plain/6c2d7b39a6e57621ea21f8efbcb94fb6eb4e1807..5b428fce4566ed627ad61f204935aaa8bc367932:/wizard/shell.py diff --git a/wizard/shell.py b/wizard/shell.py index 6870712..b8d4bd1 100644 --- a/wizard/shell.py +++ b/wizard/shell.py @@ -55,6 +55,7 @@ class Shell(object): """ def __init__(self, dry = False): self.dry = dry + self.cwd = None def call(self, *args, **kwargs): """ Performs a system call. The actual executable and options should @@ -127,7 +128,7 @@ class Shell(object): # ourself, and then setting up a # SIGCHILD handler to write a single byte to the pipe to get # us out of select() when a subprocess exits. - proc = subprocess.Popen(args, stdout=stdout, stderr=stderr, stdin=stdin) + proc = subprocess.Popen(args, stdout=stdout, stderr=stderr, stdin=stdin, cwd=self.cwd, ) if self._async(proc, args, **kwargs): return proc stdout, stderr = proc.communicate(kwargs["input"]) @@ -194,6 +195,8 @@ class Shell(object): on working directory context. Keyword arguments are the same as :meth:`call`. """ + if os.getuid(): + return self.call(*args, **kwargs) uid = os.stat(os.getcwd()).st_uid # consider also checking ruid? if uid != os.geteuid(): @@ -213,6 +216,12 @@ class Shell(object): """ kwargs["strip"] = True return self.call(*args, **kwargs) + def setcwd(self, cwd): + """ + Sets the directory processes are executed in. This sets a value + to be passed as the ``cwd`` argument to ``subprocess.Popen``. + """ + self.cwd = cwd class ParallelShell(Shell): """ @@ -279,7 +288,7 @@ class ParallelShell(Shell): Blocking call that waits for an open subprocess slot. This is automatically called by :meth:`Shell.call`. """ - # XXX: This API sucks; the actuall call/callAsUser call should + # XXX: This API sucks; the actual call/callAsUser call should # probably block automatically (unless I have a good reason not to) # bail out immediately on initial ramp up if len(self.running) < self.max: return @@ -313,6 +322,12 @@ class ParallelShell(Shell): return on_success(stdout, stderr) +# Setup a convenience global instance +shell = Shell() +call = shell.call +callAsUser = shell.callAsUser +safeCall = shell.safeCall +eval = shell.eval class DummyParallelShell(ParallelShell): """Same API as :class:`ParallelShell`, but doesn't actually