From 49cc4a9d4ed8f50db668034bba7d4b12121d526c 2011-05-27 18:21:15 From: MinRK Date: 2011-05-27 18:21:15 Subject: [PATCH] store exit code in user_ns['_exit_code'] _exit_code is an equivalent to `$?` in bash. It always has the most recent exit value of a shell.system subprocess. --- diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py index d431c49..037b86b 100644 --- a/IPython/core/interactiveshell.py +++ b/IPython/core/interactiveshell.py @@ -1890,8 +1890,10 @@ class InteractiveShell(SingletonConfigurable, Magic): # if they really want a background process. raise OSError("Background processes not supported.") - # don't return the result, always return None - system(self.var_expand(cmd, depth=2)) + # we explicitly do NOT return the subprocess status code, because + # a non-None value would trigger :func:`sys.displayhook` calls. + # Instead, we store the exit_code in user_ns. + self.user_ns['_exit_code'] = system(self.var_expand(cmd, depth=2)) def system_raw(self, cmd): """Call the given cmd in a subprocess using os.system @@ -1901,8 +1903,10 @@ class InteractiveShell(SingletonConfigurable, Magic): cmd : str Command to execute. """ - # don't return the result, always return None - os.system(self.var_expand(cmd, depth=2)) + # We explicitly do NOT return the subprocess status code, because + # a non-None value would trigger :func:`sys.displayhook` calls. + # Instead, we store the exit_code in user_ns. + self.user_ns['_exit_code'] = os.system(self.var_expand(cmd, depth=2)) # use piped system by default, because it is better behaved system = system_piped diff --git a/IPython/utils/_process_posix.py b/IPython/utils/_process_posix.py index e10945a..19df99b 100644 --- a/IPython/utils/_process_posix.py +++ b/IPython/utils/_process_posix.py @@ -130,9 +130,7 @@ class ProcessHandler(object): Returns ------- - None : we explicitly do NOT return the subprocess status code, as this - utility is meant to be used extensively in IPython, where any return - value would trigger :func:`sys.displayhook` calls. + int : child's exitstatus """ pcmd = self._make_cmd(cmd) # Patterns to match on the output, for pexpect. We read input and @@ -181,6 +179,7 @@ class ProcessHandler(object): finally: # Ensure the subprocess really is terminated child.terminate(force=True) + return child.exitstatus def _make_cmd(self, cmd): return '%s -c "%s"' % (self.sh, cmd) diff --git a/IPython/utils/_process_win32.py b/IPython/utils/_process_win32.py index 1d8bd94..094cc9b 100644 --- a/IPython/utils/_process_win32.py +++ b/IPython/utils/_process_win32.py @@ -96,6 +96,9 @@ def _system_body(p): line = line.decode(enc, 'replace') print(line, file=sys.stderr) + # Wait to finish for returncode + return p.wait() + def system(cmd): """Win32 version of os.system() that works with network shares. @@ -116,7 +119,7 @@ def system(cmd): with AvoidUNCPath() as path: if path is not None: cmd = '"pushd %s &&"%s' % (path, cmd) - process_handler(cmd, _system_body) + return process_handler(cmd, _system_body) def getoutput(cmd):