2012-12-29 9 views
33

Ho trovato documentazione su subprocess.check_output() ma non riesco a trovarne uno con argomenti e la documentazione non è molto approfondita. Sto usando Python 3 (ma sto cercando di eseguire un file Python 2 a Python 3)Come si usa subprocess.check_output() in Python?

Sto cercando di eseguire questo comando: python py2.py -i test.txt

-i è un argomento posizionale per argparse, test.txt è ciò che il -i è, py2.py è il file per eseguire

ho provato un sacco di (non di lavoro) le variazioni tra cui: py2output = subprocess.check_output([str('python py2.py '),'-i', 'test.txt'])

py2output = subprocess.check_output([str('python'),'py2.py','-i', test.txt'])

+1

Che cosa è successo esattamente quando non hanno funzionato? – khagler

+1

Cercando di eseguire un file Python 2 tramite Python 3? No, non succederà. Python 3 non è intenzionalmente retrocompatibile con Python 2. Dovresti eseguire '2to3' per * starters * per far funzionare il tuo file in Python 3. – Makoto

+1

@Makoto: Sta provando a eseguire l'interprete Python 2 all'interno di un Script Python 3, che è perfettamente ragionevole. (E dalla sua domanda precedente, capita di sapere che lo sta facendo in modo specifico come soluzione per esattamente i problemi a cui stai pensando, ma qui non è rilevante.) – abarnert

risposta

45

La risposta giusta è:

py2output = subprocess.check_output(['python','py2.py','-i', 'test.txt']) 

Per dimostrare, qui sono i miei due programmi:

py2.py:

import sys 
print sys.argv 

py3.py:

import subprocess 
py2output = subprocess.check_output(['python', 'py2.py', '-i', 'test.txt']) 
print('py2 said:', py2output) 

eseguirlo :

$ python3 py3.py 
py2 said: b"['py2.py', '-i', 'test.txt']\n" 

Ecco cosa c'è di sbagliato con ciascuno dei vostri versioni:

py2output = subprocess.check_output([str('python py2.py '),'-i', 'test.txt']) 

In primo luogo, str('python py2.py') è esattamente la stessa cosa di 'python py2.py' -Sei prendere una str, e chiamando str per convertirlo in un str. Ciò rende il codice più difficile da leggere, più lungo e persino più lento, senza aggiungere alcun vantaggio.

Più seriamente, python py2.py non può essere un singolo argomento, a meno che non si stia effettivamente tentando di eseguire un programma denominato, ad esempio, /usr/bin/python\ py2.py. Quale non sei; stai cercando di eseguire, ad esempio, /usr/bin/python con il primo argomento py2.py. Quindi, è necessario renderli elementi separati nella lista.

La tua seconda versione lo risolve, ma ti manca lo ' prima dello test.txt'. Questo dovrebbe darti un SyntaxError, probabilmente dicendo EOL while scanning string literal.

Nel frattempo, non sono sicuro di come abbia trovato la documentazione ma non è stato possibile trovare alcun esempio con argomenti. Il primo esempio è:

>>> subprocess.check_output(["echo", "Hello World!"]) 
b'Hello World!\n' 

che chiama il comando "echo" con un ulteriore argomento, "Hello World!".

anche:

-i è un argomento posizionale per argparse, test.txt è ciò che il -i è

Sono abbastanza sicuro -i è non un argomento posizionale, ma un argomento opzionale. Altrimenti, la seconda metà della frase non ha senso.

+0

ora ho provato con 2 argomenti in argparse. Ho provato a inserire questo comando nel sottoprocesso: 'python py2.py -i test.txt -l ong' Ho provato questo sottoprocesso in base alla risposta:' py2output = subprocess.check_output (["python", "py2.py", "-i", "test.txt", "- l", "ong"]) 'ma non funziona. –

+1

@ user1925847: Cosa intendi per "non funziona"? Questo non è un commento utile. Se lo fai bene, funziona, come dimostra la mia risposta. Quindi ovviamente hai fatto qualcosa di sbagliato. Ma è impossibile indovinare cosa. Come ho detto in un commento sulla domanda principale: mostraci i tuoi script e dicci quale sia l'output atteso o effettivo, o non c'è speranza di indovinare cosa stai facendo male. – abarnert

+1

e non dimenticare di rilevare le eccezioni CalledProcessError ** e ** OSError. –

2

Aggiungendo a quello citato da @abarnert

uno migliore è quello di catturare l'eccezione

import subprocess 
try: 
    py2output = subprocess.check_output(['python', 'py2.py', '-i', 'test.txt'],stderr= subprocess.STDOUT) 
    #print('py2 said:', py2output) 
    print "here" 
except subprocess.CalledProcessError as e: 
    print "Calledprocerr" 

questo stderr = subprocess.STDOUT è per fare in modo non ottenete l'errore filenotfound in stderr- che non può essere di solito catturato in filenotfoundexception, altrimenti si finirebbe per ottenere

python: can't open file 'py2.py': [Errno 2] No such file or directory 

infatti una soluzione migliore potrebbe essere quella di verificare se il file/script esiste e quindi eseguire il file/script