Python: subprocess call with shell=False not working

I am using Python script to invoke a Java virtual machine. The following command works:

subprocess.call(["./rvm"], shell=False)  # works
subprocess.call(["./rvm xyz"], shell=True) # works

But,

subprocess.call(["./rvm xyz"], shell=False) # not working

does not work. Python documentation advices to avoid shell=True.


You need to split the commands into separate strings:

subprocess.call(["./rvm", "xyz"], shell=False)

A string will work when shell=True but you need a list of args when shell=False

The shlex module is useful more so for more complicated commands and dealing with input but good to learn about:

import shlex

cmd = "python  foo.py"
subprocess.call(shlex.split(cmd), shell=False)

shlex tut


If you want to use shell=True, this is legit, otherwise it would have been removed from the standard library. The documentation doesn't say to avoid it, it says:

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.

But in your case you are not constructing the command from user input, your command is constant, so your code doesn't present the shell injection issue. You are in control of what the shell will execute, and if your code is not malicious per se, you are safe.

Example of shell injection

To explain why the shell injection is so bad, this is the example used in the documentation:

>>> 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...

Edit

With the additional information you have provided editing the question, stick to Padraic's answer. You should use shell=True only when necessary.