527 Stimmen

Bash-Befehle in Python ausführen

Auf meinem lokalen Rechner 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.

Wenn ich dann denselben Code auf einem Server ausführe, erhalte ich 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

Ich habe also eine print bashCommand das mir dann den Befehl im Terminal ausgibt, bevor es ihn mit os.system() .

Natürlich erhalte ich wieder den Fehler (verursacht durch os.system(bashCommand) ), aber vor diesem Fehler gibt es den Befehl im Terminal aus. Dann habe ich diese Ausgabe einfach kopiert und in das Terminal eingefügt und die Eingabetaste gedrückt und es funktioniert...

Hat jemand eine Ahnung, was hier los ist?

528voto

tripleee Punkte 155951

Um auf die früheren Antworten einzugehen, gibt es eine Reihe von Details, die häufig übersehen werden.

  • Bevorzugt subprocess.run() über subprocess.check_call() und Freunde über subprocess.call() über subprocess.Popen() über os.system() über os.popen()
  • Verstehen und wahrscheinlich verwenden text=True auch bekannt als universal_newlines=True .
  • Verstehen Sie die Bedeutung von shell=True o shell=False und wie sie das Zitieren und die Verfügbarkeit von Shell-Annehmlichkeiten verändert.
  • Verstehen Sie die Unterschiede zwischen sh und Bash
  • Verstehen Sie, dass ein Unterprozess von seinem übergeordneten Prozess getrennt ist und den übergeordneten Prozess im Allgemeinen nicht ändern kann.
  • Vermeiden Sie es, den Python-Interpreter als einen Unterprozess von Python auszuführen.

Diese Themen werden im Folgenden etwas ausführlicher behandelt.

Bevorzugt subprocess.run() o subprocess.check_call()

En subprocess.Popen() Funktion ist ein Arbeitstier auf niedriger Ebene, aber es ist schwierig, sie richtig zu benutzen, und man muss am Ende mehrere Codezeilen kopieren/einfügen ... die praktischerweise bereits in der Standardbibliothek als eine Reihe von Wrapper-Funktionen auf höherer Ebene für verschiedene Zwecke vorhanden sind, die im Folgenden genauer vorgestellt werden.

Hier ist ein Absatz aus der Dokumentation :

Der empfohlene Ansatz zum Aufrufen von Unterprozessen ist die Verwendung der run() Funktion für alle Anwendungsfälle, die sie bearbeiten kann. Für fortgeschrittene Anwendungsfälle wird die zugrunde liegende Popen Schnittstelle kann direkt verwendet werden.

Leider ist die Verfügbarkeit dieser Wrapper-Funktionen von Python-Version zu Python-Version unterschiedlich.

  • subprocess.run() wurde offiziell in Python 3.5 eingeführt. Es soll alle der folgenden ersetzen.
  • subprocess.check_output() wurde in Python 2.7 / 3.1 eingeführt. Es ist im Grunde äquivalent zu subprocess.run(..., check=True, stdout=subprocess.PIPE).stdout
  • subprocess.check_call() wurde in Python 2.5 eingeführt. Es ist im Grunde äquivalent zu subprocess.run(..., check=True)
  • subprocess.call() wurde in Python 2.4 im Original eingeführt subprocess Modul ( PEP-324 ). Dies entspricht im Wesentlichen subprocess.run(...).returncode

High-Level-API vs. subprocess.Popen()

Die umgestaltete und erweiterte subprocess.run() ist logischer und vielseitiger als die älteren Legacy-Funktionen, die sie ersetzt. Sie gibt eine CompletedProcess Objekt, das über verschiedene Methoden verfügt, mit denen Sie den Exit-Status, die Standardausgabe und einige andere Ergebnisse und Statusindikatoren des beendeten Unterprozesses abrufen können.

subprocess.run() ist der richtige Weg, wenn Sie einfach ein Programm ausführen und die Kontrolle an Python zurückgeben wollen. Für komplexere Szenarien (Hintergrundprozesse, vielleicht mit interaktiver E/A mit dem übergeordneten Python-Programm) müssen Sie immer noch subprocess.Popen() und kümmern Sie sich selbst um alle Klempnerarbeiten. Dies erfordert ein ziemlich kompliziertes Verständnis aller beweglichen Teile und sollte nicht auf die leichte Schulter genommen werden. Die einfachere Popen Objekt steht für den (möglicherweise noch laufenden) Prozess, der für den Rest der Lebensdauer des Unterprozesses von Ihrem Code verwaltet werden muss.

Es sollte vielleicht hervorgehoben werden, dass nur subprocess.Popen() schafft lediglich einen Prozess. Wenn Sie es dabei belassen, haben Sie einen Unterprozess, der gleichzeitig mit Python läuft, also einen "Hintergrundprozess". Wenn er keine Eingaben oder Ausgaben tätigen oder sich anderweitig mit Ihnen abstimmen muss, kann er parallel zu Ihrem Python-Programm nützliche Arbeit leisten.

Vermeiden Sie os.system() y os.popen()

Seit ewigen Zeiten (naja, seit Python 2.5) ist die os Modul-Dokumentation hat die Empfehlung enthalten, die subprocess über os.system() :

En subprocess Modul bietet leistungsfähigere Möglichkeiten zum Starten neuer Prozesse und zum Abrufen ihrer Ergebnisse; die Verwendung dieses Moduls ist der Verwendung dieser Funktion vorzuziehen.

Die Probleme mit system() sind, dass er offensichtlich systemabhängig ist und keine Möglichkeiten zur Interaktion mit dem Unterprozess bietet. Er wird einfach ausgeführt, wobei Standardausgabe und 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 Werten ungleich Null auch etwas systemabhängig ist).

PEP-324 (der bereits oben erwähnt wurde) enthält eine ausführlichere Begründung, warum os.system problematisch ist und wie subprocess versucht, diese Probleme zu lösen.

os.popen() war früher noch mehr dringend abgeraten :

Veraltet seit Version 2.6: Diese Funktion ist obsolet. Verwenden Sie die subprocess Modul.

Irgendwann in Python 3 wurde sie jedoch neu implementiert und verwendet nun einfach subprocess und leitet weiter zur subprocess.Popen() Dokumentation für Details.

Verstehen und in der Regel verwenden check=True

Sie werden auch feststellen, dass subprocess.call() hat viele der gleichen Einschränkungen wie os.system() . Bei regelmäßiger Verwendung sollten Sie in der Regel prüfen, ob der Prozess erfolgreich abgeschlossen wurde, was subprocess.check_call() y subprocess.check_output() do (wobei letzterer auch die Standardausgabe des beendeten Unterprozesses zurückgibt). In ähnlicher Weise sollten Sie normalerweise check=True avec subprocess.run() es sei denn, Sie müssen ausdrücklich zulassen, dass der Unterprozess einen Fehlerstatus zurückgibt.

In der Praxis, mit check=True o subprocess.check_* wirft Python ein CalledProcessError Ausnahme wenn der Unterprozess einen Exit-Status ungleich Null zurückgibt.

Ein häufiger Fehler bei subprocess.run() ist zu unterlassen check=True und sich wundern, wenn nachgelagerter Code fehlschlägt, wenn der Unterprozess fehlgeschlagen ist.

Andererseits ist ein häufiges Problem bei check_call() y check_output() war, dass Benutzer, die diese Funktionen blind verwendeten, überrascht waren, wenn die Ausnahme ausgelöst wurde, z. B. wenn grep hat keine Übereinstimmung gefunden. (Sie sollten wahrscheinlich ersetzen grep mit nativem Python-Code sowieso, 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 dies gehandhabt werden soll.

Verstehen und wahrscheinlich benutzen text=True alias universal_newlines=True

Seit Python 3 sind Python-interne Zeichenketten Unicode-Zeichenketten. Es gibt jedoch keine Garantie, dass ein Unterprozess Unicode-Ausgaben oder überhaupt Zeichenketten erzeugt.

(Falls die Unterschiede nicht sofort ersichtlich sind: Ned Batchelder's Pragmatischer Unicode ist eine empfohlene, wenn nicht gar obligatorische Lektüre. Es gibt eine 36-minütige Videopräsentation hinter dem Link, wenn Sie dies bevorzugen, obwohl das Lesen der Seite selbst wahrscheinlich deutlich weniger Zeit in Anspruch nimmt).

Tief im Inneren muss Python eine bytes Puffer und interpretieren ihn irgendwie. Enthält er einen Blob mit Binärdaten, wird er sollte nicht in eine Unicode-Zeichenkette dekodiert werden, weil das ein fehleranfälliges und fehlerverursachendes Verhalten ist - genau die Art von lästigem Verhalten, das viele Python-2-Skripte befallen hat, bevor es eine Möglichkeit gab, zwischen kodiertem Text und binären Daten zu unterscheiden.

Mit text=True teilen Sie Python mit, dass Sie tatsächlich Textdaten in der Standardkodierung des Systems zurückerwarten und dass diese nach bestem Wissen und Gewissen in eine Python-Zeichenkette (Unicode) dekodiert werden sollen (normalerweise UTF-8 auf jedem halbwegs aktuellen System, außer vielleicht Windows?)

Wenn das so ist no was Sie zurückfordern, gibt Python Ihnen nur bytes Zeichenketten im stdout y stderr Strings. Vielleicht werden Sie zu einem späteren Zeitpunkt do Sie wissen, dass es sich um Textstrings handelt, und Sie kennen ihre Kodierung. Dann können Sie sie dekodieren.

normal = subprocess.run([external, arg],
    stdout=subprocess.PIPE, stderr=subprocess.PIPE,
    check=True,
    text=True)
print(normal.stdout)

convoluted = subprocess.run([external, arg],
    stdout=subprocess.PIPE, stderr=subprocess.PIPE,
    check=True)
# You have to know (or guess) the encoding
print(convoluted.stdout.decode('utf-8'))

Mit Python 3.7 wurde der kürzere, anschaulichere und verständlichere Alias text für das Schlüsselwortargument, das zuvor etwas irreführend als universal_newlines .

Verstehen Sie shell=True vs shell=False

Mit shell=True übergeben Sie eine einzelne Zeichenkette an Ihre Shell, und die Shell übernimmt sie.

Mit shell=False übergeben Sie eine Liste von Argumenten an das Betriebssystem, wobei Sie die Shell umgehen.

Wenn man keine Shell hat, speichert man einen Prozess und entledigt sich einer eine ziemlich große Menge an versteckter Komplexität, die Bugs oder sogar Sicherheitsprobleme enthalten kann oder auch nicht.

Auf der anderen Seite, wenn Sie keine Shell haben, haben Sie keine Umleitung, Wildcard-Expansion, Job-Kontrolle und eine große Anzahl von anderen Shell-Funktionen.

Ein häufiger Fehler ist die Verwendung von shell=True und dann noch Python eine Liste von Token übergeben, oder andersherum. Das funktioniert zwar in einigen Fällen, ist aber sehr undefiniert und könnte auf interessante Weise scheitern.

# XXX AVOID THIS BUG
buggy = subprocess.run('dig +short stackoverflow.com')

# XXX AVOID THIS BUG TOO
broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    shell=True)

# XXX DEFINITELY AVOID THIS
pathological = subprocess.run(['dig +short stackoverflow.com'],
    shell=True)

correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    # Probably don't forget these, too
    check=True, text=True)

# XXX Probably better avoid shell=True
# but this is nominally correct
fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
    shell=True,
    # Probably don't forget these, too
    check=True, text=True)

Die übliche Erwiderung "aber bei mir funktioniert es" ist kein nützliches Gegenargument, wenn man nicht genau weiß, unter welchen Umständen es nicht mehr funktionieren könnte.

Um es kurz zusammenzufassen, die korrekte Verwendung sieht wie folgt aus

subprocess.run("string for 'the shell' to parse", shell=True)
# or
subprocess.run(["list", "of", "tokenized strings"]) # shell=False

Wenn Sie die Shell vermeiden wollen, aber zu faul sind oder nicht wissen, wie Sie eine Zeichenkette in eine Liste von Token zerlegen können, beachten Sie, dass shlex.split() kann dies für Sie tun.

subprocess.run(shlex.split("no string for 'the shell' to parse"))  # shell=False
# equivalent to
# subprocess.run(["no", "string", "for", "the shell", "to", "parse"])

Die reguläre split() funktioniert hier nicht, da es die Anführungszeichen nicht beibehält. Beachten Sie im obigen Beispiel, wie "the shell" ist eine einzelne Zeichenkette.

Refactoring-Beispiel

Sehr oft können die Funktionen der Shell durch nativen Python-Code ersetzt werden. Einfaches Awk oder sed Skripte sollten stattdessen wahrscheinlich einfach in Python übersetzt werden.

Um dies teilweise zu veranschaulichen, hier ein typisches, aber etwas albernes Beispiel, das viele Shell-Funktionen beinhaltet.

cmd = '''while read -r x;
   do ping -c 3 "$x" | grep 'min/avg/max'
   done <hosts.txt'''

# Trivial but horrible
results = subprocess.run(
    cmd, shell=True, universal_newlines=True, check=True)
print(results.stdout)

# Reimplement with shell=False
with open('hosts.txt') as hosts:
    for host in hosts:
        host = host.rstrip('\n')  # drop newline
        ping = subprocess.run(
             ['ping', '-c', '3', host],
             text=True,
             stdout=subprocess.PIPE,
             check=True)
        for line in ping.stdout.split('\n'):
             if 'min/avg/max' in line:
                 print('{}: {}'.format(host, line))

Hier sind einige Dinge zu beachten:

  • Mit shell=False Sie brauchen die Anführungszeichen nicht, die die Shell für Zeichenketten verlangt. Wenn Sie trotzdem Anführungszeichen setzen, ist das wahrscheinlich ein Fehler.
  • Oft ist es sinnvoll, so wenig Code wie möglich in einem Unterprozess auszuführen. So haben Sie mehr Kontrolle über die Ausführung Ihres Python-Codes.
  • Allerdings sind komplexe Shell-Pipelines mühsam und manchmal schwierig in Python zu reimplementieren.

Der überarbeitete Code veranschaulicht auch, wie viel die Shell mit einer sehr knappen Syntax wirklich für Sie tut - im Guten wie im Schlechten. Python sagt explizit ist besser als implizit aber der Python-Code es ziemlich langatmig und sieht wohl komplexer aus, als es tatsächlich ist. Andererseits bietet es eine Reihe von Punkten, an denen man mitten in etwas anderem die Kontrolle übernehmen kann, wie zum Beispiel die Verbesserung, dass wir den Hostnamen einfach zusammen mit der Ausgabe des Shell-Befehls einfügen können. (Das ist auch in der Shell keineswegs schwierig, aber auf Kosten einer weiteren Ablenkung und vielleicht eines weiteren Prozesses.)

Gemeinsame Shell-Konstrukte

Der Vollständigkeit halber finden Sie hier kurze Erklärungen zu einigen dieser Shell-Funktionen und einige Hinweise darauf, wie sie möglicherweise durch native Python-Funktionen ersetzt werden können.

  • Globbing, auch bekannt als Wildcard-Expansion, kann ersetzt werden durch glob.glob() oder sehr oft mit einfachen Python-String-Vergleichen wie for file in os.listdir('.'): if not file.endswith('.png'): continue . Bash hat verschiedene andere Erweiterungsmöglichkeiten wie .{png,jpg} Klammererweiterung und {1..100} sowie die Tilde-Erweiterung ( ~ auf Ihr Home-Verzeichnis erweitert, und allgemeiner ~account in das Heimatverzeichnis eines anderen Benutzers)
  • Shell-Variablen wie $SHELL o $my_exported_var können manchmal einfach durch Python-Variablen ersetzt werden. Exportierte Shell-Variablen sind z.B. verfügbar als os.environ['SHELL'] (die Bedeutung von export ist es, die Variable für Unterprozesse verfügbar zu machen - eine Variable, die für Unterprozesse nicht verfügbar ist, ist natürlich auch nicht für Python verfügbar, das als Unterprozess der Shell läuft, oder umgekehrt. Die env= Schlüsselwortargument für subprocess Methoden können Sie die Umgebung des Unterprozesses als Wörterbuch definieren. Das ist also eine Möglichkeit, eine Python-Variable für einen Unterprozess sichtbar zu machen). Mit shell=False müssen Sie wissen, wie Sie Anführungszeichen entfernen können; zum Beispiel, cd "$HOME" ist gleichbedeutend mit os.chdir(os.environ['HOME']) ohne Anführungszeichen um den Verzeichnisnamen. (Sehr oft cd ist ohnehin nicht sinnvoll oder notwendig, und viele Anfänger lassen die doppelten Anführungszeichen um die Variable weg und kommen damit durch bis eines Tages ... )
  • Die Umleitung ermöglicht es Ihnen, von einer Datei als Standardeingabe zu lesen und Ihre Standardausgabe in eine Datei zu schreiben. grep 'foo' <inputfile >outputfile öffnet outputfile zum Schreiben und inputfile zum Lesen und übergibt seinen Inhalt als Standardeingabe an grep , dessen Standardausgabe dann in outputfile . Dies ist im Allgemeinen nicht schwer durch nativen Python-Code zu ersetzen.
  • Pipelines sind eine Form der Umlenkung. echo foo | nl führt zwei Unterprozesse aus, wobei die Standardausgabe von echo ist die Standardeingabe von nl (auf Betriebssystemebene, in Unix-ähnlichen Systemen, ist dies ein einzelnes Dateihandle). Wenn Sie ein oder beide Enden der Pipeline nicht durch nativen Python-Code ersetzen können, sollten Sie vielleicht doch über die Verwendung einer Shell nachdenken, vor allem, wenn die Pipeline mehr als zwei oder drei Prozesse hat (sehen Sie sich jedoch die pipes Modul in der Python-Standardbibliothek oder eine Reihe von moderneren und vielseitigeren Wettbewerbern).
  • Mit der Auftragssteuerung können Sie Aufträge unterbrechen, im Hintergrund laufen lassen, wieder in den Vordergrund bringen usw. Die grundlegenden Unix-Signale zum Anhalten und Fortsetzen eines Prozesses sind natürlich auch in Python verfügbar. Aber Jobs sind eine übergeordnete Abstraktion in der Shell, die Prozessgruppen usw. beinhaltet, die man verstehen muss, wenn man so etwas mit Python machen will.
  • Das Zitieren in der Shell ist potenziell verwirrend, bis Sie verstehen, dass alles ist im Grunde eine Zeichenkette. Also ls -l / ist gleichbedeutend mit 'ls' '-l' '/' aber die Anführungszeichen um Literale herum sind völlig optional. Nicht in Anführungszeichen gesetzte Zeichenketten, die Shell-Metazeichen enthalten, werden einer Parametererweiterung, einer Leerraum-Tokenisierung und einer Platzhaltererweiterung unterzogen; doppelte Anführungszeichen verhindern die Leerraum-Tokenisierung und die Platzhaltererweiterung, erlauben aber Parametererweiterungen (Variablensubstitution, Befehlssubstitution und Backslash-Verarbeitung). Dies ist in der Theorie einfach, kann aber verwirrend sein, vor allem wenn es mehrere Interpretationsschichten gibt (z. B. bei einem entfernten Shell-Befehl).

Verstehen Sie die Unterschiede zwischen sh und Bash

subprocess führt Ihre Shell-Befehle mit /bin/sh wenn Sie nicht ausdrücklich etwas anderes verlangen (außer natürlich unter Windows, wo der Wert des Parameters COMSPEC variabel). Dies bedeutet, dass [verschiedene reine Bash-Funktionen wie Arrays, [[ usw.](https://stackoverflow.com/a/42666651/874188) sind nicht verfügbar.

Wenn Sie eine reine Bash-Syntax verwenden müssen, können Sie den Pfad zur Shell als executable='/bin/bash' (wenn Ihre Bash woanders installiert ist, müssen Sie den Pfad natürlich anpassen).

subprocess.run('''
    # This for loop syntax is Bash only
    for((i=1;i<=$#;i++)); do
        # Arrays are Bash-only
        array[i]+=123
    done''',
    shell=True, check=True,
    executable='/bin/bash')

A subprocess ist von seinem Elternteil getrennt und kann ihn nicht ändern

Ein weit verbreiteter Fehler ist es, etwas zu tun wie

subprocess.run('cd /tmp', shell=True)
subprocess.run('pwd', shell=True)  # Oops, doesn't print /tmp

Dasselbe passiert, wenn der erste Unterprozess versucht, eine Umgebungsvariable zu setzen, die natürlich verschwunden ist, wenn Sie einen anderen Unterprozess starten, usw.

Ein Kindprozess läuft völlig getrennt von Python, und wenn er beendet wird, hat Python keine Ahnung, was er getan hat (abgesehen von den vagen Indikatoren, die es aus dem Exit-Status und der Ausgabe des Kindprozesses ableiten kann). Ein Kindprozess kann im Allgemeinen die Umgebung des Elternprozesses nicht verändern; er kann keine Variablen setzen, das Arbeitsverzeichnis wechseln oder, mit anderen Worten, mit seinem Elternprozess kommunizieren, ohne dass dieser mit ihm zusammenarbeitet.

Die unmittelbare Lösung in diesem speziellen Fall besteht darin, beide Befehle in einem einzigen Unterprozess auszuführen;

subprocess.run('cd /tmp; pwd', shell=True)

obwohl dieser spezielle Anwendungsfall offensichtlich nicht sehr nützlich ist; verwenden Sie stattdessen die cwd Schlüsselwortargument, oder einfach os.chdir() bevor Sie den Unterprozess starten. In ähnlicher Weise können Sie beim Setzen einer Variablen die Umgebung des aktuellen Prozesses (und damit auch seiner Kinder) über

os.environ['foo'] = 'bar'

oder übergeben Sie eine Umgebungseinstellung an einen Kindprozess mit

subprocess.run('echo "$foo"', shell=True, env={'foo': 'bar'})

(ganz zu schweigen von der offensichtlichen Umstrukturierung subprocess.run(['echo', 'bar']) aber echo ist natürlich ein schlechtes Beispiel für etwas, das in einem Unterprozess laufen sollte).

Python nicht von Python aus ausführen

Dies ist ein etwas zweifelhafter Ratschlag; es gibt sicherlich Situationen, in denen es sinnvoll oder sogar zwingend erforderlich ist, den Python-Interpreter als Unterprozess eines Python-Skripts auszuführen. Aber sehr häufig ist der richtige Ansatz einfach der, dass import das andere Python-Modul in Ihr aufrufendes Skript ein und rufen dessen Funktionen direkt auf.

Wenn das andere Python-Skript unter Ihrer Kontrolle ist und es sich nicht um ein Modul handelt, sollten Sie es zu einem machen . (Diese Antwort ist bereits zu lang, so dass ich hier nicht ins Detail gehen werde).

Wenn Sie Parallelität benötigen, können Sie Python-Funktionen in Unterprozessen mit der multiprocessing Modul. Außerdem gibt es threading der mehrere Aufgaben in einem einzigen Prozess ausführt (was leichter ist und Ihnen mehr Kontrolle gibt, aber auch mehr Einschränkungen mit sich bringt, da die Threads innerhalb eines Prozesses eng gekoppelt und an einen einzigen GIL .)

470voto

user225312 Punkte 117771

Verwenden Sie nicht os.system . Sie wurde zugunsten folgender Methoden vernachlässigt Unterprozess . Von der docs : "Dieses Modul soll mehrere ältere Module und Funktionen ersetzen: os.system , os.spawn ".

Wie in Ihrem Fall:

import subprocess

bashCommand = "cwm --rdf test.rdf --ntriples > test.nt"
process = subprocess.Popen(bashCommand.split(), stdout=subprocess.PIPE)
output, error = process.communicate()

58voto

Jakob Bowyer Punkte 32375

Aufruf mit Unterprozess

import subprocess
subprocess.Popen("cwm --rdf test.rdf --ntriples > test.nt")

Der Fehler, den Sie erhalten, scheint daran zu liegen, dass kein Swap-Modul auf dem Server vorhanden ist. Sie sollten Swap auf dem Server installieren und dann das Skript erneut ausführen

30voto

Razor Punkte 377

Es ist möglich, das Bash-Programm mit dem Parameter -c zur Ausführung der Befehle zu verwenden:

bashCommand = "cwm --rdf test.rdf --ntriples > test.nt"
output = subprocess.check_output(['bash','-c', bashCommand])

23voto

David Daniel Punkte 487

Sie können verwenden subprocess , aber ich hatte immer das Gefühl, dass es nicht eine "Pythonic" Weg, es zu tun war. Also habe ich Sultan entwickelt (schamloses Plug-in), das die Ausführung von Kommandozeilenfunktionen erleichtert.

https://github.com/aeroxis/sultan

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X