Reputation: 430
Using subprocess.popen to call an external program within my script. I have been unable to get it to work without shell=True, and have added an assert statement to make things less dangerous (I think).
Relevant code lines:
import subprocess
import re
import argparse
parser = argparse.ArgumentParser(description="options")
parser.add_argument("-p", "--prefix", help="prefix for output files")
args = parser.parse_args()
assert re.match("^[a-zA-Z0-9_]+$", args.prefix), "non-alphanumeric characters found"
command = "my_external_program -t type -f %s -m 1 -M 1 -N 0 -H -p 16" % args.prefix
external_stacks_call = subprocess.Popen(command, shell=True, stdout=open(args.prefix + ".log.txt", "a"), stderr=open(args.prefix + ".log.txt", "a"))
external_stacks_call.wait()
questions are as follows:
I have looked at several pages here and elsewhere about the dangers of the shell=True option, and the dangers of shell=True, but I have not found a good source of how to avoid using it for an external program
Upvotes: 1
Views: 372
Reputation: 36872
shell=True
will escape the spaces, however you can also provide a list of args for the command line
command = ["my_external_program", "-t", "type", "-f", str(args.prefix),
"-m", "1", "-M", "1", "-N", "0", "-H", "-p", "16"]
This will allow the module to interface with the shell correctly, more safely
Without shell=True
special characters will be escaped, so the equivalent of your original command would be
$ my_external_program\ -t\ type\ -f
etc.
This is an advantage because the shell can then escape all kinds of special characters in the same way
Upvotes: 2