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
.
In addition to Enrico.bacis' answer, there are two ways to call programs. With
shell=True
, give it a full command string. Withshell=False
, give it a list.If you do shell tricks like
*.jpg
or2> /dev/null
, useshell=True
; but in general I suggestshell=False
-- it's more durable as Enrico said.source
output
You need to split the commands into separate strings:
A string will work when
shell=True
but you need a list of args whenshell=False
The shlex module is useful more so for more complicated commands and dealing with input but good to learn about:
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: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:
Edit
With the additional information you have provided editing the question, stick to Padraic's answer. You should use
shell=True
only when necessary.Instead of using the filename directory, add the word
python
in front of it, provided that you've added python path to your environmental variables. If you're not sure, you can always rerun the python installer, once again, provided that you have a new version of python.Here's what I mean: