How To Fix It
args = ['script.py', 'first argument', 'second argument']
subprocess.call(['python2.7'] + args)
- Don't use
shell=True
- Pass each argument as a separate list item; don't concatenate them into a string.
Why It Fails (with shell=True
)
Let's take a simple case:
args = [ 'script.py', 'first argument' 'second argument' ]
args_str = ' '.join(args)
subprocess.call(['python2.7', args_str], shell=True)
What does this actually do?
# the above is the same as running this at a shell
sh -c python2.7 'script.py first argument second argument'
And what does that actually do? It runs python2.7
with no arguments at all (as the argument list is interpreted as $0
to the sh -c
instance, but the script passed in the first element of the list contains only the string python2.7
and doesn't look at its $0
at all).
Why It Fails (without shell=True
)
Let's take a simple case:
args = [ 'script.py', 'first argument' 'second argument' ]
args_str = ' '.join(args)
subprocess.call(['python2.7', args_str])
What does this actually do?
# the above is the same as running this at a shell
python2.7 'script.py first argument second argument'
...and what does that do, even if you have a script.py
in your current directory?
python2.7: can't open file 'script.py first argument second argument': [Errno 2] No such file or directory
Why did that happen? Because you made your arguments part of the script's filename, and no filename with those argument values as part of its name exists.