Reputation: 1759
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
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