Rabarberski
Rabarberski

Reputation: 24942

How to get resulting subprocess command string

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'.

Upvotes: 11

Views: 5088

Answers (2)

user492203
user492203

Reputation:

Since Python 3.8, there's an shlex.join() function:

>>> shlex.join(['ls', '-l'])
'ls -l'

Upvotes: 3

Pierre GM
Pierre GM

Reputation: 20359

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.

Upvotes: 18

Related Questions