Reputation: 9969
On Windows, you make a subprocess call by passing a list of string arguments that it then reformats as a single string to call the relevant command. It does this by a series of rules as outline in the documentation here.
On Windows, an args sequence is converted to a string that can be parsed using the following rules (which correspond to the rules used by the MS C runtime):
- Arguments are delimited by white space, which is either a space or a tab.
- A string surrounded by double quotation marks is interpreted as a single argument, regardless of white space contained within. A quoted string can be embedded in an argument.
- A double quotation mark preceded by a backslash is interpreted as a literal double quotation mark.
- Backslashes are interpreted literally, unless they immediately precede a double quotation mark.
- If backslashes immediately precede a double quotation mark, every pair of backslashes is interpreted as a literal backslash. If the number of backslashes is odd, the last backslash escapes the next double quotation mark as described in rule
However in practice this can be hard to get right, as it's unclear exactly how the strings are being interpreted. And there can be trial and error in figuring out how to properly format the command.
Is there a way I can just determine what string subprocess would formulate? That way I can inspect it and ensure it's being formulated correctly as well as logging it better than just logging the list form of the command.
Upvotes: 3
Views: 116
Reputation: 9969
I dug into the actual subprocess module and found an answer in there in fact. There's a function called list2cmdline
that's used to just take a list passed to Popen
and turn it into a single string of commandline arguments. It can just be called on with the list to get the result I need:
import subprocess
name = "Monty Python's Flying Circus"
path = r"C:\path\to\files"
subprocess.list2cmdline(["file.py", name, path])
# 'file.py "Monty Python\'s Flying Circus" C:\\path\\to\\files'
Upvotes: 5