Qual è la differenza tra sottoprocesso Popen e call (come posso usarli)?


178

Voglio chiamare un programma esterno da Python. Ho usato entrambi Popen()e call()per farlo.

Qual è la differenza tra i due?

Il mio obiettivo specifico è eseguire il seguente comando da Python. Non sono sicuro di come funzionano i reindirizzamenti.

./my_script.sh > output

Ho letto la documentazione e dice che call()è una funzione di convenienza o una funzione di scelta rapida. Perdiamo energia usando call()invece di Popen()?


Quale parte della documentazione ti ha confuso? La definizione di call()sembra essere molto chiara. Puoi fornire un preventivo o un link in modo da sapere su cosa concentrarci in una risposta?
S. Lott,

Risposte:


265

Esistono due modi per eseguire il reindirizzamento. Entrambi si applicano a uno subprocess.Popeno subprocess.call.

  1. Imposta l'argomento della parola chiave shell = Trueo executable = /path/to/the/shelle specifica il comando così come lo hai lì.

  2. Poiché stai semplicemente reindirizzando l'output su un file, imposta l'argomento della parola chiave

    stdout = an_open_writeable_file_object

    dove l'oggetto punta al outputfile.

subprocess.Popenè più generale di subprocess.call.

Popennon si blocca, consentendoti di interagire con il processo mentre è in esecuzione o di continuare con altre cose nel tuo programma Python. La chiamata a Popenrestituisce un Popenoggetto.

call fa blocco. Mentre supporta tutti gli stessi argomenti del Popencostruttore, quindi è ancora possibile impostare l'output del processo, le variabili ambientali, ecc., Lo script attende il completamento del programma e callrestituisce un codice che rappresenta lo stato di uscita del processo.

returncode = call(*args, **kwargs) 

è fondamentalmente lo stesso di chiamare

returncode = Popen(*args, **kwargs).wait()

callè solo una funzione di convenienza. La sua implementazione in CPython è in subprocess.py :

def call(*popenargs, timeout=None, **kwargs):
    """Run command with arguments.  Wait for command to complete or
    timeout, then return the returncode attribute.

    The arguments are the same as for the Popen constructor.  Example:

    retcode = call(["ls", "-l"])
    """
    with Popen(*popenargs, **kwargs) as p:
        try:
            return p.wait(timeout=timeout)
        except:
            p.kill()
            p.wait()
            raise

Come puoi vedere, è un involucro sottile in giro Popen.


17
Fondamentalmente Popen e call sono funzioni asincrone e sincrone rispettivamente utilizzate per eseguire comandi Linux.
user3016020

1
Qual è il vantaggio dell'utilizzo di popen? Non sarebbe sicuro aspettare fino a quando il programma chiamato termina per primo?
Tom,

4
@ Tom Spesso no. Che cosa succede se si desidera leggere alcuni output, quindi inviare più input al programma, leggere più output che risulta da tale input, ripetere?
AGF

@ user3016020 Presumo che questo valga anche per i comandi di Windows? Destra?
domih,

7

L'altra risposta è molto completa, ma ecco una regola empirica:

  • call sta bloccando:

    call('notepad.exe')
    print('hello')  # only executed when notepad is closed
  • Popen non blocca:

    Popen('notepad.exe')
    print('hello')  # immediately executed
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.