4

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?

1
  • try to separate each parm with a comma if you want to use it as list Commented Aug 25, 2020 at 15:41

2 Answers 2

5

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

Sign up to request clarification or add additional context in comments.

2 Comments

You've got some typos there, and I think all your arguments need to be strings.
Right, forgot about that. Updated the answer
2

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']) 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.