Was ist der Unterschied zwischen dem Unterprozess Popen und dem Aufruf (wie kann ich sie verwenden)?


178

Ich möchte ein externes Programm von Python aus aufrufen. Ich habe beides benutzt Popen()und das call()zu tun.

Was ist der Unterschied zwischen den beiden?

Mein spezifisches Ziel ist es, den folgenden Befehl von Python aus auszuführen. Ich bin nicht sicher, wie Weiterleitungen funktionieren.

./my_script.sh > output

Ich habe die Dokumentation gelesen und es heißt, dass dies call()eine Komfortfunktion oder eine Verknüpfungsfunktion ist. Verlieren wir Energie, wenn wir call()statt verwenden Popen()?


Welcher Teil der Dokumentation hat Sie verwirrt? Die Definition von call()scheint sehr klar zu sein. Können Sie ein Angebot oder einen Link angeben, damit wir wissen, worauf wir uns bei einer Antwort konzentrieren müssen?
S.Lott

Antworten:


265

Es gibt zwei Möglichkeiten, die Umleitung durchzuführen. Beide gelten entweder für subprocess.Popenoder subprocess.call.

  1. Setzen Sie das Schlüsselwortargument shell = Trueoder executable = /path/to/the/shellund geben Sie den Befehl so an, wie Sie ihn dort haben.

  2. Da Sie die Ausgabe nur in eine Datei umleiten, legen Sie das Schlüsselwortargument fest

    stdout = an_open_writeable_file_object

    wo das Objekt auf die outputDatei zeigt.

subprocess.Popenist allgemeiner als subprocess.call.

Popenblockiert nicht, sodass Sie mit dem Prozess interagieren können, während er ausgeführt wird, oder mit anderen Dingen in Ihrem Python-Programm fortfahren können. Der Aufruf zum PopenZurückgeben eines PopenObjekts.

call tut Block. Obwohl es dieselben Argumente wie der PopenKonstruktor unterstützt, sodass Sie weiterhin die Ausgabe des Prozesses, Umgebungsvariablen usw. festlegen können, wartet Ihr Skript auf den Abschluss des Programms und callgibt einen Code zurück, der den Beendigungsstatus des Prozesses darstellt.

returncode = call(*args, **kwargs) 

ist im Grunde das gleiche wie anrufen

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

callist nur eine Komfortfunktion. Die Implementierung in CPython erfolgt 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

Wie Sie sehen können, ist es eine dünne Hülle herum Popen.


17
Grundsätzlich sind Popen und Call asynchrone und synchrone Funktionen, die jeweils zum Ausführen von Linux-Befehlen verwendet werden.
user3016020

1
Was ist der Vorteil der Verwendung von Popen? Wäre es nicht sicher zu warten, bis das aufgerufene Programm zuerst beendet ist?
Tom

4
@ Tom Oft nicht. Was ist, wenn Sie eine Ausgabe lesen, dann mehr Eingaben an das Programm senden, mehr Ausgaben lesen möchten, die sich aus dieser Eingabe ergeben, wiederholen?
Agf

@ user3016020 Ich gehe davon aus, dass dies auch für Windows-Befehle gilt. Richtig?
Domih

7

Die andere Antwort ist sehr vollständig, aber hier ist eine Faustregel:

  • call blockiert:

    call('notepad.exe')
    print('hello')  # only executed when notepad is closed
  • Popen ist nicht blockierend:

    Popen('notepad.exe')
    print('hello')  # immediately executed
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.