I have Python subprocess calls which are formatted as a sequence of arguments (like subprocess.Popen(['ls','-l'])
instead of a single string (i.e. subprocess.Popen('ls -l')
).
When using sequenced arguments like I did, is there a way to get the resulting string that is sent to the shell (for debugging purposes)?
One simple approach would be to join all arguments together myself. But I doubt this would in all cases be identical to what subprocess does, since the main reason for using a sequence is to 'allow[s] the module to take care of any required escaping and quoting of arguments'.
Since Python 3.8, there's an shlex.join()
function:
>>> shlex.join(['ls', '-l'])
'ls -l'
As mentioned in a comment, subprocess
comes with (not documented in the docs pages) list2cmdline
that transforms a list of arguments into a single string.
According to the source doc, list2cmdline
is used mostly on Windows:
On Windows: the Popen class uses CreateProcess() to execute the child program, which operates on strings. If args is a sequence, it will be converted to a string using the list2cmdline method. Please note that not all MS Windows applications interpret the command line the same way: The list2cmdline is designed for applications using the same rules as the MS C runtime.
Nevertheless, it's quite usable on other OSes.
EDIT
Should you need the reverse operation (ie, splitting a command line into a list of properly tokenized arguments), you'll want to use the shlex.split
function, as illustrated in the doc of subprocess
.
>>> help(subprocess.list2cmdline)
Help on function list2cmdline in module subprocess:
list2cmdline(seq)
Translate a sequence of arguments into a command line
string, using the same rules as the MS C runtime:
1) Arguments are delimited by white space, which is either a
space or a tab.
2) 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.
3) A double quotation mark preceded by a backslash is
interpreted as a literal double quotation mark.
4) Backslashes are interpreted literally, unless they
immediately precede a double quotation mark.
5) 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 3.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With