diff -r 95d1adf144ee Doc/library/os.rst --- a/Doc/library/os.rst Sat Nov 03 14:37:37 2012 +0200 +++ b/Doc/library/os.rst Mon Nov 05 20:52:55 2012 +0200 @@ -2269,6 +2269,15 @@ .. versionadded:: 3.3 +.. function :: get_shell() + + Return the path to default shell. + + For unix system returns path to ``sh``, for windows returns path to ``cmd.exe``. + + .. versionadded:: 3.4 + + Linux extended attributes ~~~~~~~~~~~~~~~~~~~~~~~~~ diff -r 95d1adf144ee Lib/os.py --- a/Lib/os.py Sat Nov 03 14:37:37 2012 +0200 +++ b/Lib/os.py Mon Nov 05 20:52:55 2012 +0200 @@ -1006,3 +1006,30 @@ raise TypeError("invalid fd type (%s, expected integer)" % type(fd)) import io return io.open(fd, *args, **kwargs) + + +def get_shell(): + """Return the path to default shell.""" + if sys.platform == "win32": + return _get_shell_for_windows() + else: + return _get_shell_for_unix() + + +def _get_shell_for_windows(): + """Return the path to default shell for Windows""" + return environ.get("COMSPEC", "cmd.exe") + + +def _get_shell_for_unix(): + """Return the path to default shell for Unix""" + for path in confstr("CS_PATH").split(pathsep): + sh = sep.join((path, "sh")) + try: + mode = stat(sh).st_mode + except OSError: + pass + else: + if st.S_ISREG(mode): + return sh + raise FileNotFound("sh") diff -r 95d1adf144ee Lib/test/test_os.py --- a/Lib/test/test_os.py Sat Nov 03 14:37:37 2012 +0200 +++ b/Lib/test/test_os.py Mon Nov 05 20:52:55 2012 +0200 @@ -2134,6 +2134,19 @@ else: self.fail("No exception thrown by {}".format(func)) + +class TestGetShell(unittest.TestCase): + def test_get_shell(self): + shell = os.get_shell() + param = "/c" if sys.platform == 'win32' else "-c" + s = subprocess.Popen([shell, param, "echo test"], + stdout=subprocess.PIPE) + stdout, stderr = s.communicate() + self.assertIn(b"test", stdout) + self.assertIsNone(stderr) + self.assertEqual(0, s.returncode) + + @support.reap_threads def test_main(): support.run_unittest( @@ -2163,6 +2176,7 @@ Win32DeprecatedBytesAPI, TermsizeTests, OSErrorTests, + TestGetShell, ) if __name__ == "__main__":