Auf meinem lokalen Computer führe ich ein Python-Skript aus, das diese Zeile enthält
bashCommand = "cwm --rdf test.rdf --ntriples > test.nt"
os.system(bashCommand)
Das funktioniert gut.
Dann führe ich denselben Code auf einem Server aus und erhalte die folgende Fehlermeldung
'import site' failed; use -v for traceback
Traceback (most recent call last):
File "/usr/bin/cwm", line 48, in <module>
from swap import diag
ImportError: No module named swap
Also habe ich dann ein eingefügt, print bashCommand
das mich als den Befehl im Terminal druckt, bevor es ausgeführt wirdos.system()
.
Natürlich bekomme ich wieder den Fehler (verursacht durch os.system(bashCommand)
), aber vor diesem Fehler wird der Befehl im Terminal gedruckt. Dann habe ich einfach diese Ausgabe kopiert und eine Kopie in das Terminal eingefügt und die Eingabetaste gedrückt und es funktioniert ...
Hat jemand eine Ahnung, was los ist?
cwm
. Vielleicht haben Sie eine Konfiguration in Ihrer.bashrc
, die die Umgebung für die interaktive Bash-Verwendung einrichtet?cwm
. Oder vielleicht gibt es einen Unterschied in PATH und verschiedene Versionen voncwm
werden aufgerufen. Oder verschiedene Versionen von Python. Es ist wirklich schwer, dies ohne Zugang zur Maschine herauszufinden ...Antworten:
Nicht benutzen
os.system
. Es wurde zugunsten des Teilprozesses abgelehnt . Aus der docs : „Dieses Modul soll mehrere älteren Module und Funktionen ersetzen:os.system
,os.spawn
“.Wie in Ihrem Fall:
quelle
cd 'path\to\somewhere'
einen Befehl ausführen musste, gefolgt von einem anderen Bash-Befehl, der irgendwo ausgeführt werden musste. @ user225312cwd
Argument für Popen verwenden:subprocess.Popen(..., cwd='path\to\somewhere')
stdout=file
leitet die Ausgabe in diesem Fall in eine Datei um. Sie wird implementiert> file
). Es wäre falsch,..., '>', 'file']
den letzten Befehl zu übergeben, der die Umleitung erwartet (es funktioniert nicht ohne eine Shell, und wenn Sie eine Shell verwenden, sollten Sie den Befehl als Zeichenfolge übergeben)Um die früheren Antworten hier etwas zu erweitern, gibt es eine Reihe von Details, die häufig übersehen werden.
subprocess.run()
übersubprocess.check_call()
und Freundesubprocess.call()
übersubprocess.Popen()
überos.system()
überos.popen()
text=True
auchuniversal_newlines=True
.shell=True
odershell=False
und wie sich das Angebot ändert, und die Verfügbarkeit von Shell-Annehmlichkeiten.sh
und BashDiese Themen werden im Folgenden ausführlicher behandelt.
Bevorzugen
subprocess.run()
odersubprocess.check_call()
Das
subprocess.Popen()
Funktion ist ein Arbeitspferd auf niedriger Ebene, aber es ist schwierig, sie richtig zu verwenden, und Sie kopieren / fügen am Ende mehrere Codezeilen ein ... die bequemerweise bereits in der Standardbibliothek als Satz von Wrapper-Funktionen auf höherer Ebene für verschiedene Zwecke vorhanden sind. die im Folgenden näher erläutert werden.Hier ist ein Absatz aus der Dokumentation :
Leider unterscheidet sich die Verfügbarkeit dieser Wrapper-Funktionen zwischen den Python-Versionen.
subprocess.run()
wurde offiziell in Python 3.5 eingeführt. Es soll alle folgenden ersetzen.subprocess.check_output()
wurde in Python 2.7 / 3.1 eingeführt. Es ist im Grunde gleichbedeutend mitsubprocess.run(..., check=True, stdout=subprocess.PIPE).stdout
subprocess.check_call()
wurde in Python 2.5 eingeführt. Es ist im Grunde gleichbedeutend mitsubprocess.run(..., check=True)
subprocess.call()
wurde in Python 2.4 im Originalmodulsubprocess
( PEP-324 ) eingeführt. Es ist im Grunde gleichbedeutend mitsubprocess.run(...).returncode
High-Level-API vs.
subprocess.Popen()
Das überarbeitete und erweiterte System
subprocess.run()
ist logischer und vielseitiger als die älteren Legacy-Funktionen, die es ersetzt. Es gibt einCompletedProcess
Objekt mit verschiedenen Methoden zurück, mit denen Sie den Exit-Status, die Standardausgabe und einige andere Ergebnisse und Statusindikatoren aus dem fertigen Unterprozess abrufen können.subprocess.run()
Dies ist der richtige Weg, wenn Sie lediglich ein Programm benötigen, um die Steuerung auszuführen und an Python zurückzugeben. Für komplexere Szenarien (Hintergrundprozesse, möglicherweise mit interaktiver E / A mit dem übergeordneten Python-Programm) müssen Sie weiterhinsubprocess.Popen()
alle Installationen selbst verwenden und pflegen. Dies erfordert ein ziemlich kompliziertes Verständnis aller beweglichen Teile und sollte nicht leichtfertig durchgeführt werden. Das einfacherePopen
Objekt stellt den (möglicherweise noch laufenden) Prozess dar, der für den Rest der Lebensdauer des Unterprozesses aus Ihrem Code verwaltet werden muss.Es sollte vielleicht betont werden, dass nur
subprocess.Popen()
ein Prozess entsteht. Wenn Sie es dabei belassen, wird neben Python gleichzeitig ein Unterprozess ausgeführt, also ein "Hintergrund" -Prozess. Wenn es keine Eingabe oder Ausgabe oder anderweitige Koordinierung mit Ihnen vornehmen muss, kann es nützliche Arbeit parallel zu Ihrem Python-Programm leisten.Vermeiden Sie
os.system()
undos.popen()
Seit ewiger Zeit (na ja, da Python 2.5) die
os
Moduldokumentation hat die Empfehlung enthalten ist, bevorzugensubprocess
überos.system()
:Die Probleme dabei
system()
sind, dass es offensichtlich systemabhängig ist und keine Möglichkeiten zur Interaktion mit dem Unterprozess bietet. Es wird einfach ausgeführt, wobei die Standardausgabe und der Standardfehler außerhalb der Reichweite von Python liegen. Die einzige Information, die Python zurückerhält, ist der Exit-Status des Befehls (Null bedeutet Erfolg, obwohl die Bedeutung von Nicht-Null-Werten auch etwas systemabhängig ist).PEP-324 (das bereits oben erwähnt wurde) enthält eine detailliertere Begründung dafür, warum dies
os.system
problematisch ist und wiesubprocess
versucht wird, diese Probleme zu lösen.os.popen()
war früher noch stärker entmutigt :Seit einiger Zeit in Python 3 wurde es jedoch neu implementiert, um es einfach zu verwenden
subprocess
, und leitet zursubprocess.Popen()
Dokumentation weiter, um weitere Informationen zu erhalten.Verstehe und benutze es normalerweise
check=True
Sie werden auch feststellen, dass
subprocess.call()
es viele der gleichen Einschränkungen gibt wieos.system()
. Bei regelmäßiger Verwendung sollten Sie im Allgemeinen prüfen, ob der Prozess erfolgreich abgeschlossen wurde, wassubprocess.check_call()
undsubprocess.check_output()
was (wobei letzterer auch die Standardausgabe des fertigen Unterprozesses zurückgibt). In ähnlicher Weise sollten Sie normalerweisecheck=True
mit verwenden, essubprocess.run()
sei denn, Sie müssen dem Unterprozess ausdrücklich erlauben, einen Fehlerstatus zurückzugeben.In der Praxis löst Python mit
check=True
odersubprocess.check_*
eineCalledProcessError
Ausnahme aus, wenn der Unterprozess einen Exit-Status ungleich Null zurückgibt.Ein häufiger Fehler
subprocess.run()
besteht darin, wegzulassencheck=True
und überrascht zu sein, wenn Downstream-Code fehlschlägt, wenn der Unterprozess fehlschlägt.Andererseits bestand ein häufiges Problem mit
check_call()
und darin,check_output()
dass Benutzer, die diese Funktionen blind verwendeten, überrascht waren, als die Ausnahme ausgelöst wurde, z. B. wenngrep
keine Übereinstimmung gefunden wurde. (Sie sollten wahrscheinlichgrep
trotzdem durch nativen Python-Code ersetzen , wie unten beschrieben.)Alles in allem müssen Sie verstehen, wie Shell-Befehle einen Exit-Code zurückgeben und unter welchen Bedingungen sie einen Exit-Code ungleich Null (Fehler) zurückgeben, und eine bewusste Entscheidung treffen, wie genau damit umgegangen werden soll.
Verstehe und benutze wahrscheinlich
text=True
akauniversal_newlines=True
Seit Python 3 sind in Python interne Zeichenfolgen Unicode-Zeichenfolgen. Es gibt jedoch keine Garantie dafür, dass ein Unterprozess eine Unicode-Ausgabe oder überhaupt Zeichenfolgen generiert.
(Wenn die Unterschiede nicht sofort offensichtlich sind, wird das Lesen von Pragmatic Unicode von Ned Batchelder empfohlen, wenn nicht sogar obligatorisch. Wenn Sie es vorziehen, befindet sich hinter dem Link eine 36-minütige Videopräsentation, obwohl das Lesen der Seite selbst wahrscheinlich erheblich weniger Zeit in Anspruch nimmt. )
Tief im Inneren muss Python einen
bytes
Puffer holen und ihn irgendwie interpretieren. Wenn es einen Blob von Binärdaten enthält, sollte es nicht in eine Unicode-Zeichenfolge dekodiert werden, da dies ein fehleranfälliges und fehlerauslösendes Verhalten ist - genau die Art von lästigem Verhalten, das viele Python 2-Skripte durcheinander brachte, bevor es einen Weg dazu gab richtig zwischen codiertem Text und Binärdaten unterscheiden.Mit
text=True
teilen Sie Python mit, dass Sie tatsächlich Textdaten in der Standardcodierung des Systems zurückerwarten und dass diese nach besten Python-Fähigkeiten in eine Python-Zeichenfolge (Unicode) dekodiert werden sollten (normalerweise UTF-8 bei mäßig bis zu Datumssystem, außer vielleicht Windows?)Wenn Sie dies nicht zurückfordern, gibt Python Ihnen nur
bytes
Zeichenfolgen in den Zeichenfolgenstdout
undstderr
. An einigen Vielleicht zeigen Sie später noch wissen , dass sie Text - Strings , nachdem alle waren, und Sie wissen , ihre Codierung. Dann können Sie sie dekodieren.Python 3.7 führte den kürzeren, aussagekräftigeren und verständlicheren Alias
text
für das Keyword-Argument ein, das zuvor etwas irreführend genannt wurdeuniversal_newlines
.Verstehe
shell=True
vs.shell=False
Übergeben
shell=True
Sie eine einzelne Zeichenfolge an Ihre Shell, und die Shell übernimmt sie von dort.Wenn
shell=False
Sie eine Liste von Argumenten an das Betriebssystem übergeben, umgehen Sie die Shell.Wenn Sie keine Shell haben, speichern Sie einen Prozess und beseitigen eine ziemlich große Menge an versteckter Komplexität, die Fehler oder sogar Sicherheitsprobleme enthalten kann oder nicht.
Wenn Sie jedoch keine Shell haben, verfügen Sie nicht über Umleitung, Platzhaltererweiterung, Jobsteuerung und eine große Anzahl anderer Shell-Funktionen.
Ein häufiger Fehler besteht darin
shell=True
, Python eine Liste von Token zu verwenden und diese dann weiterzuleiten oder umgekehrt. Dies funktioniert in einigen Fällen, ist jedoch sehr schlecht definiert und kann auf interessante Weise brechen.Die übliche Erwiderung "aber es funktioniert für mich" ist keine nützliche Gegenargumentation, es sei denn, Sie verstehen genau, unter welchen Umständen sie nicht mehr funktionieren könnte.
Refactoring-Beispiel
Sehr oft können die Funktionen der Shell durch nativen Python-Code ersetzt werden. Simple Awk oder
sed
Skripte sollten wahrscheinlich stattdessen einfach in Python übersetzt werden.Um dies teilweise zu veranschaulichen, ist hier ein typisches, aber etwas albernes Beispiel, das viele Shell-Merkmale beinhaltet.
Einige Dinge, die hier zu beachten sind:
shell=False
brauchen Sie nicht das Zitat, das die Shell um Strings benötigt. Das Setzen von Anführungszeichen ist wahrscheinlich ein Fehler.Der überarbeitete Code zeigt auch, wie viel die Shell mit einer sehr knappen Syntax wirklich für Sie tut - zum Guten oder zum Schlechten. Python sagt, explizit ist besser als implizit, aber der Python-Code ist ziemlich ausführlich und sieht wohl komplexer aus, als dies wirklich ist. Auf der anderen Seite bietet es eine Reihe von Punkten, an denen Sie mitten in etwas anderem die Kontrolle übernehmen können. Dies wird trivial durch die Verbesserung veranschaulicht, dass wir den Hostnamen einfach zusammen mit der Ausgabe des Shell-Befehls einfügen können. (Dies ist auch in der Shell keineswegs schwierig, sondern auf Kosten einer weiteren Umleitung und möglicherweise eines weiteren Prozesses.)
Gemeinsame Shell-Konstrukte
Der Vollständigkeit halber finden Sie hier kurze Erläuterungen zu einigen dieser Shell-Funktionen sowie einige Hinweise, wie sie möglicherweise durch native Python-Funktionen ersetzt werden können.
glob.glob()
oder sehr oft durch einfache Python-String-Vergleiche wie ersetzt werdenfor file in os.listdir('.'): if not file.endswith('.png'): continue
. Bash verfügt über verschiedene andere Erweiterungsfunktionen wie die.{png,jpg}
Erweiterung von Klammern und die Erweiterung{1..100}
von Tilde (wird~
in Ihr Home-Verzeichnis und allgemein~account
in das Home-Verzeichnis eines anderen Benutzers erweitert).$SHELL
oder$my_exported_var
können manchmal einfach durch Python-Variablen ersetzt werden. Exportierte Shell-Variablen sind verfügbar als z. B.os.environ['SHELL']
(die Bedeutung vonexport
besteht darin, die Variable für Unterprozesse verfügbar zu machen - eine Variable, die für Unterprozesse nicht verfügbar ist, steht Python offensichtlich nicht zur Verfügung, die als Unterprozess der Shell ausgeführt wird, oder umgekehrt. Dasenv=
Schlüsselwort Mit dem Argument fürsubprocess
Methoden können Sie die Umgebung des Unterprozesses als Wörterbuch definieren. Auf diese Weise können Sie eine Python-Variable für einen Unterprozess sichtbar machen. Mit müssenshell=False
Sie verstehen, wie Sie Anführungszeichen entfernen; ist zum Beispielcd "$HOME"
gleichbedeutend mitos.chdir(os.environ['HOME'])
ohne Anführungszeichen um die Verzeichnisnamen. (Sehr oftcd
ist sowieso nicht nützlich oder notwendig, und viele Anfänger lassen die doppelten Anführungszeichen um die Variable weg und kommen damit bis eines Tages davon ... )grep 'foo' <inputfile >outputfile
öffnet sichoutputfile
zum Schreiben undinputfile
Lesen und übergibt seinen Inhalt als Standardeingabe angrep
, dessen Standardausgabe dann landetoutputfile
. Dies ist im Allgemeinen nicht schwer durch nativen Python-Code zu ersetzen.echo foo | nl
führt zwei Unterprozesse aus, wobei die Standardausgabe vonecho
die Standardeingabe von istnl
(auf Betriebssystemebene ist dies in Unix-ähnlichen Systemen ein einzelnes Dateihandle). Wenn Sie ein oder beide Enden der Pipeline nicht durch nativen Python-Code ersetzen können, sollten Sie vielleicht doch eine Shell verwenden, insbesondere wenn die Pipeline mehr als zwei oder drei Prozesse enthält (sehen Sie sich jedoch daspipes
Modul in der Python-Standardbibliothek oder eine Nummer an von moderneren und vielseitigeren Wettbewerbern Dritter).ls -l /
also gleichbedeutend mit,'ls' '-l' '/'
aber das Zitieren um Literale ist völlig optional. Nicht zitierte Zeichenfolgen, die Shell-Metazeichen enthalten, werden einer Parametererweiterung, einer Leerzeichen-Tokenisierung und einer Platzhaltererweiterung unterzogen. Doppelte Anführungszeichen verhindern die Leerzeichen-Tokenisierung und die Platzhaltererweiterung, ermöglichen jedoch Parametererweiterungen (Variablensubstitution, Befehlssubstitution und Backslash-Verarbeitung). Dies ist theoretisch einfach, kann jedoch verwirrend werden, insbesondere wenn mehrere Interpretationsebenen vorhanden sind (z. B. ein Remote-Shell-Befehl).Verstehe die Unterschiede zwischen
sh
und Bashsubprocess
führt Ihre Shell-Befehle mit aus,/bin/sh
sofern Sie nicht ausdrücklich etwas anderes anfordern (außer natürlich unter Windows, wo der Wert derCOMSPEC
Variablen verwendet wird). Dies bedeutet, dass verschiedene Nur-Bash-Funktionen wie Arrays[[
usw. nicht verfügbar sind.Wenn Sie die Nur-Bash-Syntax verwenden müssen, können Sie den Pfad an die Shell als übergeben.
executable='/bin/bash'
Wenn Ihr Bash an einer anderen Stelle installiert ist, müssen Sie den Pfad anpassen.A
subprocess
ist von seinem übergeordneten Element getrennt und kann es nicht ändernEin etwas häufiger Fehler ist, so etwas zu tun
was neben dem Mangel an Eleganz auch einen grundlegenden Mangel an Verständnis für den "Sub" -Teil des Namens "Subprozess" verrät.
Ein untergeordneter Prozess wird vollständig getrennt von Python ausgeführt, und wenn er abgeschlossen ist, hat Python keine Ahnung, was er getan hat (abgesehen von den vagen Indikatoren, die er aus dem Beendigungsstatus ableiten und aus dem untergeordneten Prozess ausgeben kann). Ein Kind kann die Umgebung des Elternteils im Allgemeinen nicht ändern. Es kann keine Variable festlegen, das Arbeitsverzeichnis nicht ändern oder in so vielen Worten mit dem übergeordneten Element kommunizieren, ohne dass das übergeordnete Element mitarbeitet.
Die sofortige Lösung in diesem speziellen Fall besteht darin, beide Befehle in einem einzigen Unterprozess auszuführen.
obwohl für diesen speziellen Anwendungsfall die Shell offensichtlich überhaupt nicht erforderlich ist. Denken Sie daran, dass Sie die Umgebung des aktuellen Prozesses (und damit auch seiner untergeordneten Elemente) über manipulieren können
oder übergeben Sie eine Umgebungseinstellung an einen untergeordneten Prozess mit
(ganz zu schweigen von der offensichtlichen Umgestaltung
subprocess.run(['echo', 'bar'])
; aber esecho
ist natürlich ein schlechtes Beispiel für etwas, das in einem Unterprozess ausgeführt werden kann).Führen Sie Python nicht über Python aus
Dies ist ein etwas zweifelhafter Rat; Es gibt sicherlich Situationen, in denen es sinnvoll oder sogar unbedingt erforderlich ist, den Python-Interpreter als Unterprozess aus einem Python-Skript auszuführen. Sehr häufig ist es jedoch richtig, einfach
import
das andere Python-Modul in Ihr aufrufendes Skript zu integrieren und dessen Funktionen direkt aufzurufen.Wenn das andere Python-Skript unter Ihrer Kontrolle steht und kein Modul ist, sollten Sie es in eines umwandeln . (Diese Antwort ist bereits zu lang, daher werde ich hier nicht auf Details eingehen.)
Wenn Sie Parallelität benötigen, können Sie Python-Funktionen in Unterprozessen mit dem
multiprocessing
Modul ausführen . Es gibt auch Funktionen,threading
die mehrere Aufgaben in einem einzigen Prozess ausführen (was leichter ist und Ihnen mehr Kontrolle bietet, aber auch dadurch eingeschränkt ist, dass Threads innerhalb eines Prozesses eng miteinander verbunden und an eine einzelne GIL gebunden sind ).quelle
run()
blind verwendet wurde. Dascheck=True
Fehlen verursachte einen Fehler, der vermieden werden würde, wenn check_call verwendet würde - "check" ist im Namen, Sie können ihn nicht verlieren - es ist die richtige Standardeinstellung: Ignorieren Sie Fehler nicht stillschweigend. Ich habe nicht weiter gelesen.sh
aber du hast mich geschlagen. Ich versuche, die Einzelheiten so detailliert darzulegen, dass Anfänger, für die diese Fallstricke nicht offensichtlich sind, etwas langwierig werden. Ihre sollte sonst völlig ausreichen; +1stderr/stdout = subprocess.PIPE
ein höherer Leistungsaufwand als die Standardeinstellungen?os.system()
.Nennen Sie es mit Unterprozess
Der Fehler, den Sie erhalten, scheint darauf zurückzuführen zu sein, dass auf dem Server kein Swap-Modul vorhanden ist. Sie sollten Swap auf dem Server installieren und das Skript erneut ausführen
quelle
swap
Modul ist offensichtlich vorhanden, da das Ausführen des Befehls über die Shell funktioniert.shell=True
, sollten Sie eine Liste verwenden, um mehrere Argumente zu übergeben, dh['a', 'b', 'c']
anstelle von verwenden'a b c'
. Obwohl eine naive Aufteilung aufgrund> file
(Shell-Umleitung) im Befehl nicht funktioniert . Weitere DetailsEs ist möglich, dass Sie das Bash-Programm mit dem Parameter -c verwenden, um die Befehle auszuführen:
quelle
subprocess.check_output(bashCommand, shell=True)
macht das gleiche. Wenn Ihr Befehl eine statische Zeichenfolge ist, versuchen Sie, ihn selbst in eine Liste zu analysieren, und vermeiden Sie dasshell=True
; In diesem Fall benötigen Sie die Shell ohnehin für die Umleitung, oder Sie müssen sie in reines Pythonwith open('test.nt', 'w') as dest: output = subprocess.check_output(['cwm' ,'--rdf', 'test.rdf', '--ntriples'], stdout=dest, shell=False)
/bin/sh
(wird von Unterprozessen verwendet) ist nicht unbedingtbash
(Sie können keine Bashismen verwenden). Obwohl man es aufexecutable='/bin/bash
Wunsch verwenden könnte. Hier ist ein Codebeispielcheck_output()
ist hier nutzlos (die Ausgabe ist aufgrund der> file
Umleitung immer leer ; verwenden Siecheck_call()
stattdessen.Sie können verwenden
subprocess
, aber ich hatte immer das Gefühl, dass es keine "pythonische" Art war, dies zu tun. Also habe ich Sultan (schamloser Plug) erstellt, der das Ausführen von Befehlszeilenfunktionen vereinfacht.https://github.com/aeroxis/sultan
quelle
Entsprechend dem Fehler fehlt Ihnen ein Paket mit dem Namen swap auf dem Server. Dies
/usr/bin/cwm
erfordert es. Wenn Sie mit Ubuntu / Debian arbeiten, installieren Sie espython-swap
mit aptitude.quelle
swap
oder es hätte es gar nicht erst importieren sollen. können Sieimport swap
manuell? funktioniert es?sys.path
wo es funktioniert und wo nicht. Versuchen Sie dann, in den gedruckten Ordnern nach dem Swap-Ordner oder der Datei swap.py zu suchen. Wie Sven sagte, kann es ein Problem mit diesen Pfaden geben, und dies wird Ihnen helfen, es herauszufinden.Sie können auch 'os.popen' verwenden. Beispiel:
Ausgabe:
quelle
subprocess
Modul."os.popen
hat diese Warnung nicht mehr und istsubprocess.Popen()
jetzt einfach eine dünne Hülle .Um den Befehl ohne Shell auszuführen, übergeben Sie den Befehl als Liste und implementieren Sie die Umleitung in Python mit
[subprocess]
:Hinweis: Nein
> test.nt
am Ende.stdout=file
implementiert die Umleitung.Um den Befehl mit der Shell in Python auszuführen, übergeben Sie den Befehl als Zeichenfolge und aktivieren Sie
shell=True
:Hier ist die Shell für die Ausgabeumleitung verantwortlich (
> test.nt
befindet sich im Befehl).Um einen bash-Befehl auszuführen, der bashisms verwendet, geben Sie die ausführbare bash-Datei explizit an, z. B. um die Ersetzung des bash-Prozesses zu emulieren :
quelle
.split()
nicht ausreicht, wenn Zeichenfolgen in Anführungszeichen usw. stehen. Es gibt eine separate Routine,shlex.split()
die mit beliebig komplexer Shell-Syntax fertig wird..split()
funktioniert in diesem Fall.shlex.split()
kann manchmal nützlich sein, kann aber in einigen Fällen auch fehlschlagen. Es gibt sehr viele Dinge, die erwähnt werden könnten. Sie können mit dem Link zur oben angegebenen Beschreibung des Unterprozess-Tags beginnen.Die pythonische Art, dies zu tun, ist die Verwendung
subprocess.Popen
subprocess.Popen
Nimmt eine Liste, in der das erste Element der auszuführende Befehl ist, gefolgt von allen Befehlszeilenargumenten.Als Beispiel:
quelle
echo -v '"Hello Again!"'
von einfachen Anführungszeichen um die doppelten Anführungszeichen.subprocesss.Popen
, müssen Sie das resultierende Prozessobjekt verwalten (führen Sie mindestens a aus, umwait()
zu verhindern, dass es sich in einen Zombie-Prozess verwandelt).