X-Git-Url: https://scripts.mit.edu/gitweb/wizard.git/blobdiff_plain/3368f862191d6f77b2685972b9051f239db6a39b..a29acb618699431bf1fdd2c7df6d3b0a9e0282e0:/wizard/shell.py diff --git a/wizard/shell.py b/wizard/shell.py index 8660d1a..1ee9bfa 100644 --- a/wizard/shell.py +++ b/wizard/shell.py @@ -87,8 +87,7 @@ class Shell(object): >>> sh.call("cat", input='Foobar') ('Foobar', '') """ - if hasattr(self, "_wait"): - self._wait() + self._wait() kwargs.setdefault("interactive", False) kwargs.setdefault("strip", False) kwargs.setdefault("python", None) @@ -129,10 +128,15 @@ class Shell(object): # 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) - if hasattr(self, "_async"): - self._async(proc, args, **kwargs) + if self._async(proc, args, **kwargs): return proc stdout, stderr = proc.communicate(kwargs["input"]) + # can occur if we were doing interactive communication; i.e. + # we didn't pass in PIPE. + if stdout is None: + stdout = "" + if stderr is None: + stderr = "" if not kwargs["interactive"]: if kwargs["strip"]: self._log(None, stderr) @@ -143,7 +147,7 @@ class Shell(object): else: eclass = CallError raise eclass(proc.returncode, args, stdout, stderr) if kwargs["strip"]: - return stdout.rstrip("\n") + return str(stdout).rstrip("\n") return (stdout, stderr) def _log(self, stdout, stderr): """Logs the standard output and standard input from a command.""" @@ -151,6 +155,10 @@ class Shell(object): logging.debug("STDOUT:\n" + stdout) if stderr: logging.debug("STDERR:\n" + stderr) + def _wait(self): + pass + def _async(self, *args, **kwargs): + return False def callAsUser(self, *args, **kwargs): """ Performs a system call as a different user. This is only possible @@ -265,6 +273,7 @@ class ParallelShell(Shell): execution. See :meth:`Shell.call` source code for details. """ self.running[proc.pid] = (proc, args, python, on_success, on_error) + return True # so that the parent function returns def _wait(self): """ Blocking call that waits for an open subprocess slot. This is @@ -304,6 +313,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