Reputation: 137
I'm trying to initiate a command-line program with command-line options from my Python script using the run method from the subprocess module.
My command is defined as a list of strings specifying the program and options as follows (where pheno_fp
and construction_fp
are strings representing file paths in my system and exe
is a string representing the file path to the program I'm running):
step1_cmd = [exe,
"--step 1",
"--p " + pheno_fp,
"--b 1000",
"--o " + construction_fp + "dpw_leaveout"]
Not working - When I try the following, the program I want to run is started but the command I've specified is interpreted incorrectly because the program exits with an error saying "specify output file path with --o flag":
test1 = subprocess.run(step1_cmd)
Working - When I try the following, the program executes correctly, meaning all arguments are interpreted as intended:
test1 = subprocess.run(" ".join(step1_cmd), shell=True)
If I understood the documentation correctly, the former approach is the recommended usage but I can't understand why it's not working. I'm pretty sure it's formatted the same as the examples in the documentation so I'm a bit stumped. Any ideas?
Upvotes: 3
Views: 3042
Reputation: 29317
The explanation for this behavior is here:
args is required for all calls and should be a string, or a sequence of program arguments. Providing a sequence of arguments is generally preferred, as it allows the module to take care of any required escaping and quoting of arguments (e.g. to permit spaces in file names).
Example: the sequence
l = ['ls', '-l tmp']
gives an error
subprocess.run(l)
ls: illegal option --
This is because subprocess
(which is a call to Popen
) is trying to run ls "-l tmp"
.
The correct way to define a sequence of arguments is by separating them so that they can be quoted correctly
subprocess.run(['ls', '-l', 'tmp'])
Upvotes: 2
Reputation: 1246
Split each parameter with its value, like so:
step1_cmd = [exe,
"--step",
"1",
"--p",
str(pheno_fp), # if it isn't a string already
"--b",
"1000",
"--o",
str(construction_fp) + "dpw_leaveout"
]
Because when passing a list of parameters, each part is separated with a space, both options and their values
Upvotes: 4