Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 743
Rabarberski Avatar asked Aug 26 '12 12:08

Rabarberski


2 Answers

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

>>> shlex.join(['ls', '-l'])
'ls -l'
like image 81
nyuszika7h Avatar answered Sep 21 '22 18:09

nyuszika7h


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.
like image 30
Pierre GM Avatar answered Sep 19 '22 18:09

Pierre GM