Vorteile der Unterprozess über os.system

Habe ich vor kurzem stieß auf ein paar Beiträge auf stack overflow, die sagen, dass subprocess sehr viel besser ist als os.system, ich bin jedoch Schwierigkeiten haben, den genauen Vorteile.

Einige Beispiele für Dinge, die ich ausgeführt in:
https://docs.python.org/3/library/os.html#os.system

„Das subprocess-Modul bietet mehr leistungsfähige Einrichtungen zum erzeugen von neuen Prozessen und das abrufen Ihrer Ergebnisse; mit diesem Modul ist vorzuziehen, um diese Funktion zu verwenden.“

Keine Ahnung, wie es ist mächtiger obwohl, ich weiß, es ist einfacher, in vielerlei Hinsicht zu verwenden Teilprozess ist es aber tatsächlich mächtiger in irgendeiner Weise?

Weiteres Beispiel ist:

https://stackoverflow.com/a/89243/3339122

Den Vorteil, Teilprozess vs system ist, dass es flexibler ist (Sie können die stdout, stderr, die „echte“ status-code, bessere Fehlerbehandlung, usw…).

Diese post, die hat 2600+ Stimmen. Wieder konnte nicht finden, eine Ausarbeitung, was eine bessere Fehlerbehandlung-oder real-status-code.

Top-Kommentar auf diesem post ist:

Kann nicht sehen, warum Sie verwenden würden, os.system auch für quick/dirty/ein-Zeit. Teilprozess scheint so viel besser.

Wieder, ich verstehen, es macht einige Dinge etwas einfacher, aber ich kann kaum verstehen, warum zum Beispiel:

subprocess.call("netsh interface set interface \"Wi-Fi\" enable", shell=True)

ist besser als

os.system("netsh interface set interface \"Wi-Fi\" enabled")

Kann mir jemand erklären, einige Gründe, warum es so viel besser?

  • Sie eindeutig noch nicht angesehen in der API viel, weil Ihre Nutzung der subprocess.call ist falsch. Bitte Lesen Sie die API-docs und schauen Sie sich einige Beispiele der erweiterten use-cases.
  • Nur für das Protokoll. Hat es eigentlich gut funktioniert mit oder ohne shell=True. Ich habe tatsächlich die Dokumentation Lesen. Es ist auch nicht die Frage, warum mein code ist oder nicht funktioniert. Ich kann das update der Beispiel-wenn Sie möchten, Frage ist immer noch die Unterschiede zwischen Ihnen. Siehe: stackoverflow.com/questions/3172470/…, bevor Sie voreilige Schlüsse ziehen oder andere Forschung. Ich weiß, wie der code funktioniert, ich weiß nur nicht, warum ich benutze es über etwas anderes.
  • Das muss sein, einige seltsame Artefakt der windows-Implementierung. Die Tatsache, dass es „funktioniert“ auf ein OS bedeutet nicht, dass es richtig eingesetzt.
  • Mögliche Duplikate von Aufruf eines externen Kommandos in Python
InformationsquelleAutor Lain | 2017-06-23



2 Replies
  1. 16

    Erste von allen, Sie sind das Ausschneiden der Zwischenhändler; subprocess.call standardmäßig vermeidet laichen eine shell, die untersucht Ihren Befehl, und direkt erstellt der gewünschte Prozess. Dies ist wichtig, weil, neben der Effizienz Seite der Sache, Sie haben nicht viel Kontrolle über die Standard-shell Verhalten, und es eigentlich in der Regel arbeitet gegen Sie in Bezug auf die Flucht.

    Insbesondere, in der Regel Sie dies nie tun:

    subprocess.call("netsh interface set interface \"Wi-Fi\" enable")

    seit

    Wenn die Weitergabe einer einzelnen Zeichenfolge, entweder shell muss True (siehe unten), oder aber der string muss einfach name des Programms ausgeführt werden, ohne Angabe von Argumenten auf.

    Stattdessen werden Sie tun:

    subprocess.call(["netsh", "interface", "set", "interface", "Wi-Fi", "enable"])

    Merken, dass hier alle die Flucht, die Alpträume sind verschwunden. subprocess Griffe Flucht (wenn das OS will Argumente als eine einzelne Zeichenfolge – wie Windows) oder geht das getrennt Argumente direkt zu den entsprechenden syscall (execvp auf UNIX).

    Vergleichen Sie diese mit zu bewältigen, die Flucht selbst, vor allem in cross-Plattform-Weg (cmd nicht entkommen in der gleichen Weise wie POSIX sh), vor allem mit der Schale in der Mitte messing mit Ihrem Zeug (Vertrauen Sie mir, Sie wollen nicht wissen, was unheilige Chaos ist die Bereitstellung eines 100% sichere Flucht für den Befehl beim Aufruf cmd /k).

    Auch, wenn mit subprocess ohne die Schale in der Mitte sind Sie sicher, dass Sie immer richtige return-codes. Wenn es einen Fehler gibt Start des Prozesses erhalten Sie eine Python-exception, wenn man einen return-code, es ist eigentlich der Rückgabecode des gestarteten Programms. Mit os.system Sie haben keine Möglichkeit zu wissen, wenn der return-code, den Sie erhalten, kommt von der gestartete Befehl (die in der Regel ist das Standardverhalten, wenn die shell verwaltet, um es zu starten) oder ist es ein Fehler von der shell aus (wenn es nicht zu verwalten, um es zu starten).


    Neben der Argumente aufteilen/Flucht und Rückkehr-code, haben Sie die Möglichkeit, eine bessere Kontrolle über den gestarteten Prozess. Auch mit subprocess.call (das ist die basic-utility-Funktion über subprocess Funktionalitäten) können Sie umleiten stdin, stdout und stderr möglicherweise die Kommunikation mit dem Prozess gestartet. check_call ist ähnlich, und es vermeidet das Risiko zu ignorieren ein Fehler exit-code. check_output umfasst die gemeinsame Nutzung bei check_call + Erfassung aller in der Ausgabe des Programms in eine string-variable.

    Sobald Sie Vergangenheit call & Freunde (die blockieren nur als os.system), da gibt es mehr leistungsfähige Funktionen, insbesondere die Popen – Objekt ermöglicht Ihnen das arbeiten mit den gestarteten Prozess asynchron. Sie können es starten, vielleicht sprechen Sie mit ihm durch die umgeleiteten Bäche, prüfen Sie, ob es läuft von Zeit zu Zeit, während Sie andere Sachen, die darauf warten für Sie zu vervollständigen, Signale zu senden und zu töten – all das Zeug, das ist Weg, neben der reinen synchronen „Prozess starten mit default stdin/stdout/stderr durch die Schale und warten, es zu beenden“, dass os.system bietet.


    Also, um es zusammenzufassen, mit subprocess:

    • auch auf der grundlegendsten Ebene (call & friends), Sie:
      • vermeiden, Flucht, Probleme, indem eine Python-Liste von Argumenten;
      • vermeiden Sie die shell messing mit dem command-line;
      • entweder haben Sie eine Ausnahme oder die wahre exit-code des Prozesses gestartet; keine Verwirrung über Programm/shell-exit code;
      • haben die Möglichkeit zur Aufnahme von stdout und im Allgemeinen leiten Sie die standard-streams;
    • wenn Sie Popen:
      • Sie sind nicht nur eine synchrone Schnittstelle, aber Sie können tatsächlich tun andere Sachen, während dem Teilprozess ausführen;
      • Sie können Steuern, den Teilprozess (überprüfen Sie, wenn es ausgeführt wird, mit ihm zu kommunizieren, es töten).

    Gegeben, dass subprocess tut weit mehr, als os.system tun können – und in ein sicherer, flexibler (wenn man es braucht) Weg – es gibt einfach keinen Grund für die Verwendung system statt.

  2. 6

    Gibt es viele Gründe, aber der Hauptgrund ist, erwähnt direkt in der docstring:

    >>> os.system.__doc__
    'Execute the command in a subshell.'

    Fast allen Fällen, wo Sie brauchen, einen Teilprozess, es ist unerwünscht, um zu laichen eine subshell. Dies ist unnötig und verschwenderisch, es fügt eine zusätzliche Schicht von Komplexität, und stellt mehrere neue Schwachstellen und Fehlermöglichkeiten. Mit subprocess Modul schneidet die Zwischenhändler.

    • Danke, ich werde Daumen hoch für den Kommentar. Nicht genau beantworten der bessere Fehlerbehandlung, Echtzeit-status-codes, oder andere Dinge, die ich erwähnt hatte in meinem Beitrag die Leute reden über. Auch dein post macht das gleiche wie die Ihre, unsicher, was neue Sicherheitslücken/Fehler-Möglichkeits-du meinst, und alos unsicher, welche casses es wäre wünschenswert, um zu laichen eine subshell. Kann mir nicht vorstellen, die kleine Verschwendung von diesem sammeln, so viel Unterstützung ist alles.
    • Eine shell ermöglicht die Interaktion mit dem Betriebssystem. Python hat auch alle die Kraft, die notwendig für die Interaktion mit dem Betriebssystem. Warum fragt Python zu Fragen, die shell für die Interaktion mit dem Betriebssystem? Die zusätzliche Komplexität entsteht, wenn man zu übersetzen, Dinge wie Rohre und entweicht in die shell-Sprache. Erfahren Sie mehr über die Schwachstellen, Suche nach shell-injection.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.