Using variables as arguments for a command called by subprocess in Python 2.7.x
<p>I'm trying to create a basic function that will pass a filename and arguments to a program using <code>call()</code> from the <code>subprocess</code> module. The filename and arguments are variables. When I use <code>call()</code> it takes the variables but the called program reads their strings with <code>"</code> included.</p>

<p>Here's the code in question:</p>

<pre><code>from subprocess import call

def mednafen():
    print "Loading "+romname+"..."
        call(["mednafen", args, romname])
        print "Mednafen closed."
romname="kirby.zip"
args="-fs 1"
mednafen()
</code></pre>

<p>I expected this would execute</p>

<pre><code>mednafen -fs 1 kirby.zip
</code></pre>

<p>but instead it appears to interpret the variable's strings as this:</p>

<pre><code>mednafen "-fs 1" "kirby.zip"
</code></pre>

<p>Because of this, mednafen isn't able to run because it can't parse an argument that starts with <code>"</code>.
It works as expected if I use <code>shell=True</code> but that feature is apparently strongly discouraged because it's easy to exploit?</p>

<pre><code>call("mednafen "+ args +" "+romname+"; exit", shell=True)
</code></pre>

<p>Is there a way to do this without using the <code>shell=True</code> format?</p>

<p><strong>EDIT</strong>: The solution suggested by <a href="http://stackoverflow.com/users/1248008/jonas-wielicki">Jonas Wielicki</a> 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 <code>call()</code> will read them properly. <code>shlex</code> is unnecessary.</p>

<pre><code>args = ["-fs", "1"]
call(['mednafen']+args+[rom])
</code></pre>

<p><strong>My initial (less concise) solution:</strong>
<code>shlex.split()</code> 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 <code>"-fs 0"</code> I'm getting <code>-fs 0</code> like I originally wanted.</p>

<pre><code>import shlex
call(shlex.split("mednafen "+args+" "+romname))
</code></pre>

python python-2.7