Aus dem Quelltext von subprocess.py:
Unter UNIX, mit shell=True: Wenn args eine Zeichenkette ist, gibt sie die Befehlszeichenfolge an, die über die Shell ausgeführt werden soll. Wenn args eine Sequenz ist, gibt das erste Element die Befehlszeichenfolge an, und alle weiteren Elemente werden als zusätzliche Shell-Argumente behandelt.
Unter Windows: Die Popen-Klasse verwendet CreateProcess(), um das Kindprogramm auszuführen Programm auszuführen, das mit Zeichenketten arbeitet. Wenn args eine Sequenz ist, wird sie mit der Methode list2cmdline in eine Zeichenkette umgewandelt. Bitte beachten Sie, dass nicht alle MS-Windows-Anwendungen die Befehlszeile gleich interpretieren Weise interpretieren: Die list2cmdline-Methode ist für Anwendungen gedacht, die die gleichen Regeln wie die MS C-Laufzeit verwenden.
Das beantwortet nicht die Frage nach dem Grund, sondern verdeutlicht nur, dass Sie das erwartete Verhalten sehen.
Das "Warum" liegt wahrscheinlich daran, dass auf UNIX-ähnlichen Systemen Befehlsargumente tatsächlich an Anwendungen weitergegeben werden (unter Verwendung der exec*
Familie von Aufrufen) als ein Array von Zeichenketten. Mit anderen Worten: Der aufrufende Prozess entscheidet, was in JEDES Befehlszeilenargument eingeht. Wenn Sie ihm hingegen sagen, dass er eine Shell verwenden soll, hat der aufrufende Prozess nur die Möglichkeit, ein einziges Befehlszeilenargument zur Ausführung an die Shell zu übergeben: Die gesamte Befehlszeile, die ausgeführt werden soll, mit dem Namen der ausführbaren Datei und den Argumenten, als eine einzige Zeichenkette.
Unter Windows wird jedoch die gesamte Befehlszeile (gemäß der obigen Dokumentation) als eine einzige Zeichenkette an den Kindprozess übergeben. Wenn Sie sich die CreateProcess API-Dokumentation werden Sie feststellen, dass sie erwartet, dass alle Befehlszeilenargumente zu einer großen Zeichenkette zusammengefügt werden (daher der Aufruf von list2cmdline
).
Hinzu kommt die Tatsache, dass es auf UNIX-ähnlichen Systemen tatsächlich es eine Shell, die nützliche Dinge tun kann, so dass ich vermute, dass der andere Grund für den Unterschied ist, dass auf Windows, shell=True
macht nichts, deshalb funktioniert es so, wie Sie es sehen. Die einzige Möglichkeit, dass sich die beiden Systeme identisch verhalten, wäre, dass es einfach alle Befehlszeilenargumente fallen lässt, wenn shell=True
unter Windows.