2013-02-12 7 views
25

Sto usando la chiamata subprocess.Popen e in un'altra domanda ho scoperto che avevo frainteso il modo in cui Python stava generando argomenti per la riga di comando.emette la riga di comando chiamata da sottoprocesso?

La mia domanda
C'è un modo per scoprire ciò che la linea di comando effettivo è stato?

esempio di codice: -

proc = subprocess.popen(....) 
print "the commandline is %s" % proc.getCommandLine() 

Come ti scrivere getCommandLine?

risposta

41

Dipende dalla versione di Python che si sta utilizzando. In Python3.3, l'arg viene salvato in proc.args:

proc = subprocess.Popen(....) 
print("the commandline is {}".format(proc.args)) 

In Python2.7, the args not saved, è solo trasmette ad altre funzioni come _execute_child. Quindi, in questo caso, il modo migliore per ottenere la riga di comando è di salvarlo quando lo avete:

proc = subprocess.Popen(shlex.split(cmd)) 
print "the commandline is %s" % cmd 

Si noti che se avete la lista di argomenti (come ad esempio il tipo di cosa restituito da shlex.split(cmd), allora si può recuperare la stringa di riga di comando, cmd utilizzando la funzione non documentata subprocess.list2cmdline:

In [14]: import subprocess 

In [15]: import shlex 

In [16]: cmd = 'foo -a -b --bar baz' 

In [17]: shlex.split(cmd) 
Out[17]: ['foo', '-a', '-b', '--bar', 'baz'] 

In [18]: subprocess.list2cmdline(['foo', '-a', '-b', '--bar', 'baz']) 
Out[19]: 'foo -a -b --bar baz' 
+0

Sono in 2,6. E in 2.6 almeno è bene che list2cmdline non sia documentato, perché non funziona: per '--arg = foo bar' ciò che Python ACTUALLY fa è '--arg = "foo bar"' ma quello che list2cmdline dà è '" --arg = foo bar "'... ma grazie. –

+0

Penso che il problema non esista con 'list2cmdline', ma piuttosto' shlex.split'. 'shlex.split ('- arg =" foo bar "')' restituisce una lista con un singolo elemento: '['--arg = foo bar']', mentre 'shlex.split ('- arg =" foo bar "") 'divide correttamente gli argomenti:' ['--arg', '=', 'foo bar'] '. Su quest'ultima lista 'list2cmdline' funziona bene. – unutbu

+0

A proposito, il modulo 'subprocess' di Python2.6 usa' list2cmdline' per convertire 'args' in una lista ogni volta che' args' non è una stringa, quindi funziona nel senso che quello che vedi è il valore di ritorno di ' list2cmdline (args) 'è esattamente ciò che viene passato a' execvp * 'o all'equivalente di Windows. – unutbu

2

la risposta corretta alla mia domanda è in realtà che ci IS nessuna riga di comando. Il punto di sottoprocesso è che fa tutto tramite IPC. La list2cmdline fa il più vicino possibile, ma in realtà la cosa migliore da fare è guardare la lista "args", e solo sapere che sarà argv nel programma chiamato.

+2

['list2cmdline()'] (https: // hg.python.org/cpython/file/f38489a3394f/Lib/subprocess.py#l541) è utile solo su Windows per applicazioni compatibili con il modo in cui il runtime di MS C analizza la riga di comando. Converte una lista di argomenti in una stringa passata a 'CreateProcess()'. ['cmd.exe' utilizza regole diverse] (http://stackoverflow.com/q/27864103/4279). Su POSIX l'elenco viene passato direttamente a 'os.execve()' (+/- os.fsencode()). – jfs

Problemi correlati