2011-09-19 13 views
11

Quindi sto cercando di passare da os.popen a subprocess.popen come raccomandato dalla guida dell'utente. L'unico problema che ho è che non riesco a trovare un modo di fare readlines().Letture dei sottoprocessi Python()?

Così ho usato per essere in grado di fare

list = os.popen('ls -l').readlines() 

ma non posso fare

list = subprocess.Popen(['ls','-l']).readlines() 
+1

preferiscono fare 'list = subprocess.call ([ 'ls', '- l']) readlines() ' – jdborg

+2

che è sbagliato -. 'Call' restituisce solo il codice di ritorno, non è l'uscita. – agf

+0

http://stackoverflow.com/questions/2924310/whats-a-good-equivalent-to-pythons-subprocess-check-call-that-returns-the-conte – jfs

risposta

23

Con subprocess.Popen, utilizzare communicate per leggere e scrivere dati:

out, err = subprocess.Popen(['ls','-l'], stdout=subprocess.PIPE).communicate() 

Quindi puoi sempre dividere la stringa dai processi 'stdout con splitlines().

out = out.splitlines() 
+0

Pensavo che questo sarebbe stato il "bel nuovo modo" "di farlo. Grazie per la risposta, lo imposterò al termine del timeout. Mi tengo un bastone per il popen. – jdborg

+3

Il problema con 'communicate' è che si ottiene tutto l'output in una volta, il che nel caso di un' ls' non ricorsivo non è probabilmente un problema. Usando il membro 'stdout', puoi leggere riga per riga (pensa a' find'). –

25
ls = subprocess.Popen(['ls','-l'], stdout=subprocess.PIPE) 
out = ls.stdout.readlines() 

o, se si desidera leggere riga per riga (forse l'altro processo è più intenso rispetto ls):

for ln in ls.stdout: 
    # whatever 
+1

Questo approccio è preferibile alla risposta accettata in quanto consente di leggere l'output mentre il processo secondario lo produce. – Hoons

3
list = subprocess.Popen(['ls', '-l'], stdout=subprocess.PIPE).communicate()[0].splitlines() 

direttamente dal help(subprocess)

+0

Questo non è un elenco di linee, è una singola stringa multi-linea. – agf

+0

buon punto, corretto – Kimvais

8

Making a system call that returns the stdout output as a string:

lines = subprocess.check_output(['ls', '-l']).splitlines() 
+0

Bello, immagino che non sia molto conosciuto perché è solo Python 2.7+. – agf

+0

@agf: segui il link c'è un adattamento per le versioni precedenti di Python. – jfs

+0

Lo so, ho già seguito entrambi i link che hai postato (e upvoted ogni post). Sono stato sorpreso di non sapere di questa funzione di convenienza finché non ho visto che era 2.7+. – agf

3

Un modo più dettagliato di utilizzare il sottoprocesso.

 # Set the command 
     command = "ls -l" 

     # Setup the module object 
     proc = subprocess.Popen(command, 
          shell=True, 
          stdin=subprocess.PIPE, 
          stdout=subprocess.PIPE, 
          stderr=subprocess.PIPE) 

     # Communicate the command 
     stdout_value,stderr_value = proc.communicate() 

     # Once you have a valid response, split the return output  
     if stdout_value: 
      stdout_value = stdout_value.split() 
Problemi correlati