diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py index bf94a83..89e0f53 100644 --- a/IPython/core/interactiveshell.py +++ b/IPython/core/interactiveshell.py @@ -2246,6 +2246,10 @@ class InteractiveShell(SingletonConfigurable): else: cmd = py3compat.unicode_to_str(cmd) ec = os.system(cmd) + # The high byte is the exit code, the low byte is a signal number + # that we discard for now. See the docs for os.wait() + if ec > 255: + ec >>= 8 # We explicitly do NOT return the subprocess status code, because # a non-None value would trigger :func:`sys.displayhook` calls. diff --git a/IPython/core/tests/test_interactiveshell.py b/IPython/core/tests/test_interactiveshell.py index cf7f763..fce8d5c 100644 --- a/IPython/core/tests/test_interactiveshell.py +++ b/IPython/core/tests/test_interactiveshell.py @@ -414,6 +414,11 @@ class TestSystemRaw(unittest.TestCase): """ cmd = ur'''python -c "'åäö'" ''' ip.system_raw(cmd) + + def test_exit_code(self): + """Test that the exit code is parsed correctly.""" + ip.system_raw('exit 1') + self.assertEqual(ip.user_ns['_exit_code'], 1) class TestModules(unittest.TestCase, tt.TempFileMixin): def test_extraneous_loads(self):