Reputation: 11
I'm trying to create a basic function that will pass a filename and arguments to a program using call()
from the subprocess
module. The filename and arguments are variables. When I use call()
it takes the variables but the called program reads their strings with "
included.
Here's the code in question:
from subprocess import call
def mednafen():
print "Loading "+romname+"..."
call(["mednafen", args, romname])
print "Mednafen closed."
romname="kirby.zip"
args="-fs 1"
mednafen()
I expected this would execute
mednafen -fs 1 kirby.zip
but instead it appears to interpret the variable's strings as this:
mednafen "-fs 1" "kirby.zip"
Because of this, mednafen isn't able to run because it can't parse an argument that starts with "
.
It works as expected if I use shell=True
but that feature is apparently strongly discouraged because it's easy to exploit?
call("mednafen "+ args +" "+romname+"; exit", shell=True)
Is there a way to do this without using the shell=True
format?
Upvotes: 0
Views: 615
Reputation: 11
EDIT: The solution suggested by Jonas Wielicki is to make sure every single string that would normally be separated by spaces in shell syntax is listed as a separate item; That way call()
will read them properly. shlex
is unnecessary.
args = ["-fs", "1"]
call(['mednafen']+args+[rom])
My initial (less concise) solution:
shlex.split()
takes the variables/strings I feed it and converts them into a list of string literals, which in turn causes the called command to parse them correctly rather than interpreting the variables as strings within quotes.
So instead of the argument being treated like "-fs 0"
I'm getting -fs 0
like I originally wanted.
import shlex
call(shlex.split("mednafen "+args+" "+romname))
Upvotes: 1
Reputation: 798646
Well, yes. That's exactly what the documentation says it does. Create and pass a list containing the command and all arguments instead.
Upvotes: 1