Domanda

Devo essere vista qualcosa di terribilmente ovvio. Ho bisogno di eseguire un programma C, il suo output in tempo reale e, infine, analizzare la sua ultima linea, che dovrebbe essere semplice come l'ultima riga stampata è sempre lo stesso.

process = subprocess.Popen(args, shell = True,  
                           stdout = subprocess.PIPE, stderr = subprocess.PIPE)

# None indicates that the process hasn't terminated yet.
while process.poll() is None:

    # Always save the last non-emtpy line that was output by the child
    # process, as it will write an empty line when closing its stdout.
    out = process.stdout.readline()
    if out:
        last_non_empty_line = out

    if verbose:
        sys.stdout.write(out)   
        sys.stdout.flush()

# Parse 'out' here...

Una volta ogni tanto, però, l'ultima riga non viene stampata. Il valore predefinito per delle Popens bufsize è 0, per cui si suppone che sia senza buffer. Ho anche provato, senza successo, l'aggiunta di fflush (stdout) per il codice C appena prima di uscire, ma sembra che non v'è assolutamente alcuna necessità di irrigare un flusso prima di uscire un programma.

idee chiunque?

È stato utile?

Soluzione

readline() ha per tamponare il testo, in attesa di una nuova linea.

Avrai sempre una condizione di competizione - nessuna quantità di flussi di un-buffered gestirà il fatto che si sta gestire una linea, quindi il controllo per l'uscita, poi la lettura di una linea, quindi se le uscite di processo parziali, mentre si sta la gestione di una linea, non leggerete niente altro. Inoltre, il guscio è probabilmente l'introduzione di un proprio buffer.

Quindi, si potrebbe o:

  1. Usa communicate() e rinunciare alla output dettagliato mentre il sottoprocesso è in funzione.

  2. Assicurati di continuare a leggere dopo il processo è uscito, fino ad arrivare EOF.

Vorrei anche suggerire alterare il codice in modo che non c'è bisogno di usare shell=True.

Altri suggerimenti

Il problema è che si sta leggendo le linee fino alle uscite di processo, (process.poll()) mentre si utilizzati buffer a causa della bandiera shell.

Si dovrà continuare a leggere process.stdout fino a raggiungere la fine del file o la linea vuota.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top