2011-11-10 40 views
14

Ho un problema usando il subprocess.Popen o subprocess.call quando li uso per eseguire una riga di comando che genera un sacco di output, gli script Python si blocca, ma cosa è strano che dopo aver atteso un po 'di tempo, mentre la sceneggiatura è nel suo stato di sospensione, ho trovato che il lavoro comandato dalla linea cmd è stato fatto, e solo lo script è appeso.Python: subprocess.Popen e subprocess.call hang

subprocess.call(cmd, shell = True) 
#OR 
subprocess.Popen(cmd, stdout = subprocess.PIPE, stdin = subprocess.PIPE, shell = True) 
# HANGS HERE 
print "show something after subprocess" 

Si noti che l'ultima stampa non viene mai eseguita, ma in realtà il cmd è stato eseguito.

Nota anche il cmd è relativo alla porta seriale, quindi quando estrai il cavo seriale, tutto diventa perfetto e viene eseguito l'ultimo statetement di stampa. Ma quando uso il terminale tutto va bene anche se il seriale è collegato, si verifica solo con lo script python.

Grazie mille

risposta

12

Secondo la documentazione pitone, subprocess.call esegue il comando e attende la fine del processo, quindi è equivalente a subprocess.Popen seguito da Popen.wait.

Tuttavia, la documentazione del metodo Popen.wait segnala esplicitamente il problema dell'overflow del buffer e consiglia di utilizzare invece Popen.communicate. Quindi, la soluzione che state cercando dovrebbe essere qualcosa di simile:

import subprocess 
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, shell=True) 
stdout, stderr = process.communicate() 
print "show something after subprocess" 
+1

Non c'è problema nell'usare "subprocess.call' se non si utilizza" subprocess.PIPE', che l'OP non è. – interjay

+1

Non spiega perché l'output dell'istruzione 'print' non è mostrato nel genitore. 'Popen()' non aspetta il figlio anche se il processo figlio è bloccato nel tentativo di scrivere sulla pipe con il buffer completo. – jfs

2

non capisco il motivo per cui la prima linea non funziona - come non ci sono stdin/stdout/stderr redirezioni, non è necessario per il blocco.

La seconda è supposto per bloccare se il processo

  1. prevede dati tramite stdin o
  2. invia più dati stdout di un tubo può contenere wothout la lettura.

Ma poiché il sottoprocesso termina correttamente, non riesco a vedere un motivo per bloccare anche. Sei sicuro che termina davvero?

Problemi correlati