Actual meaning of 'shell=True' in subprocess Actual meaning of 'shell=True' in subprocess python python

Actual meaning of 'shell=True' in subprocess


The benefit of not calling via the shell is that you are not invoking a 'mystery program.' On POSIX, the environment variable SHELL controls which binary is invoked as the "shell." On Windows, there is no bourne shell descendent, only cmd.exe.

So invoking the shell invokes a program of the user's choosing and is platform-dependent. Generally speaking, avoid invocations via the shell.

Invoking via the shell does allow you to expand environment variables and file globs according to the shell's usual mechanism. On POSIX systems, the shell expands file globs to a list of files. On Windows, a file glob (e.g., "*.*") is not expanded by the shell, anyway (but environment variables on a command line are expanded by cmd.exe).

If you think you want environment variable expansions and file globs, research the ILS attacks of 1992-ish on network services which performed subprogram invocations via the shell. Examples include the various sendmail backdoors involving ILS.

In summary, use shell=False.


>>> import subprocess>>> subprocess.call('echo $HOME')Traceback (most recent call last):...OSError: [Errno 2] No such file or directory>>>>>> subprocess.call('echo $HOME', shell=True)/user/khong0

Setting the shell argument to a true value causes subprocess to spawn an intermediate shell process, and tell it to run the command. In other words, using an intermediate shell means that variables, glob patterns, and other special shell features in the command string are processed before the command is run. Here, in the example, $HOME was processed before the echo command. Actually, this is the case of command with shell expansion while the command ls -l considered as a simple command.

source: Subprocess Module


An example where things could go wrong with Shell=True is shown here

>>> 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 / # THIS WILL DELETE EVERYTHING IN ROOT PARTITION!!!>>> call("cat " + filename, shell=True) # Uh-oh. This will end badly...

Check the doc here: subprocess.call()