What shell is run?
This is mentioned in the Python subprocess
documentation:
The executable argument specifies the program to execute. It is very seldom needed: Usually, the program to execute is defined by the args argument. If shell=True, the executable argument specifies which shell to use. On Unix, the default shell is /bin/sh
. On Windows, the default shell is specified by the COMSPEC
environment variable. The only reason you would need to specify shell=True
on Windows is where the command you wish to execute is actually built in to the shell, eg dir, copy. You don’t need shell=True to run a batch file, nor to run a console-based executable.
/bin/sh
on Linux/MacOSX is typically an alias for bash (or bash-compatible - newer versions of Debian use dash), whereas on Unixes like Solaris, it might be classic Bourne Shell.
For Windows, it's usually cmd
or command.bat
.
Login shell or not via popen
?
I just realized that I haven't answered your 2nd question - but setting shell=True
will spawn a non-login shell (look @AndiDog's source code link, the way the shell is getting forked would create a non-login shell).
Security Implications
Also be aware that using shell=True
, while it allows you to use shell primitives and shortcuts, can also be a security risk, so be sure to check any possible inputs you might use for process spawning.
Warning Executing shell commands that incorporate unsanitized input from an untrusted source makes a program vulnerable to shell injection, a serious security flaw which can result in arbitrary command execution. For this reason, the use of shell=True is strongly discouraged in cases where the command string is constructed from external input:
>>>
>>> from subprocess import call
>>> filename = input("What file would you like to display?\n")
What file would you like to display?
non_existent; rm -rf / #
>>> call("cat " + filename, shell=True) # Uh-oh. This will end badly...
shell=False
disables all shell based features, but does not suffer from this vulnerability; see the Note in the Popen constructor documentation for helpful hints in getting shell=False to work.