dross
dross

Reputation: 1759

Using variable in subprocess command (Python)

Currently calling:

f = open('/tmp/list.txt','w')
f.write(list)
f.close()  # Make sure to close the file before call sub-process.
           # Otherwise, file content will not visible to sub-process.

process = subprocess.Popen('oscommand --file={}'.format(f.name),
                           shell=True, stdout=subprocess.PIPE)

However need to use a variable as an argument which has been generated using [ShortId][1]. Need something like:

u=ShortId()
process = subprocess.Popen('oscommand --label "The unique id is "'+u' --file={}'.format(f.name),
                               shell=True, stdout=subprocess.PIPE)

How is the escaping best handled ?

Upvotes: 1

Views: 355

Answers (1)

ShadowRanger
ShadowRanger

Reputation: 155584

This is actually easier if you stop trying to make str commands with shell=True and just use the safer, faster list based command with shell=False (the default):

u=ShortId()
cmd = ['oscommand', '--label', 'The unique id is {}'.format(u), '--file={}'.format(f.name)]
process = subprocess.Popen(cmd, stdout=subprocess.PIPE)

This avoids the risk of either the id or the file name containing shell metacharacters (say, a space) causing the command to be parsed incorrectly (or dangerously, if the string is actively malicious, e.g. a file named foo;sudo rm -rf /*).

Also note that there are better ways to do temporary files, whether or not the file is supposed to last after the Popen command finishes:

import tempfile

with tempfile.NamedTemporaryFile('w+t', delete=False) as f:
    f.write(mylist)
... rest of code here ...

Alternatively, if the file should be cleaned up automatically after use:

with tempfile.NamedTemporaryFile('w+t') as f:
    f.write(mylist)
    f.flush()
    ... rest of code using temp file ...

Upvotes: 4

Related Questions