Wie rufe ich einen externen Befehl in Python auf, als hätte ich ihn in einer Shell oder Eingabeaufforderung eingegeben?
Según docs.python.org/2/library/ "shell=True" kann ein Sicherheitsproblem darstellen.
Wie rufe ich einen externen Befehl in Python auf, als hätte ich ihn in einer Shell oder Eingabeaufforderung eingegeben?
Für die Verwendung subprocess
in Python 3.5+, das folgende tat den Trick für mich auf Linux:
import subprocess
# subprocess.run() returns a completed process object that can be inspected
c = subprocess.run(["ls", "-ltrh"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print(c.stdout.decode('utf-8'))
Wie bereits in die Dokumentation , PIPE
Werte sind Byte-Sequenzen, und um sie richtig darzustellen, sollte eine Dekodierung in Betracht gezogen werden. Für spätere Versionen von Python, text=True
y encoding='utf-8'
werden zu kwargs von subprocess.run()
.
Die Ausgabe des oben erwähnten Codes lautet:
total 113M
-rwxr-xr-x 1 farzad farzad 307 Jan 15 2018 vpnscript
-rwxrwxr-x 1 farzad farzad 204 Jan 15 2018 ex
drwxrwxr-x 4 farzad farzad 4.0K Jan 22 2018 scripts
.... # Some other lines
Verwenden Sie subprocess.call :
from subprocess import call
# Using list
call(["echo", "Hello", "world"])
# Single string argument varies across platforms so better split it
call("echo Hello world".split(" "))
Ein Beispiel (unter Linux):
import subprocess
subprocess.run('mkdir test.dir', shell=True)
Dadurch wird test.dir im aktuellen Verzeichnis erstellt. Beachten Sie, dass dies auch funktioniert:
import subprocess
subprocess.call('mkdir test.dir', shell=True)
Der entsprechende Code mit os.system lautet:
import os
os.system('mkdir test.dir')
Die beste Praxis wäre, subprocess anstelle von os zu verwenden, wobei .run gegenüber .call bevorzugt wird. Alles, was Sie über subprocess wissen müssen, ist aquí . Beachten Sie auch, dass die gesamte Python-Dokumentation zum Herunterladen verfügbar ist unter aquí . Ich habe die PDF-Datei als .zip-Datei heruntergeladen. Ich erwähne dies, weil es einen schönen Überblick über das os-Modul in tutorial.pdf (Seite 81) gibt. Außerdem ist es eine maßgebliche Quelle für Python-Programmierer.
@Nick Predley: Zur Kenntnis genommen, aber "shell=False" erfüllt nicht die gewünschte Funktion. Was genau sind die Sicherheitsbedenken und was ist die Alternative? Bitte lassen Sie es mich so schnell wie möglich wissen: Ich möchte nichts posten, was für andere, die dies lesen, Probleme verursachen könnte.
Die grundlegende Warnung ist in der Dokumentation enthalten, aber diese Frage erklärt sie ausführlicher: stackoverflow.com/questions/3172470/
Es gibt viele verschiedene Möglichkeiten, externe Befehle in Python auszuführen, und alle haben ihre eigenen Vor- und Nachteile.
Meine Kollegen und ich haben Python-Tools für die Systemadministration geschrieben, so dass wir viele externe Befehle ausführen müssen, und manchmal möchte man, dass sie blockiert oder asynchron ausgeführt werden, eine Zeitüberschreitung haben, jede Sekunde aktualisiert werden usw.
Es gibt auch verschiedene Möglichkeiten, den Rückgabecode und Fehler zu behandeln, und Sie möchten vielleicht die Ausgabe parsen und neue Eingaben machen (in einer erwarten Art von Stil). Oder Sie müssen umleiten Standardeingabe , Standardausgabe et Standardfehler auf einem anderen tty laufen zu lassen (z.B. bei Verwendung von GNU-Bildschirm ).
Sie werden also wahrscheinlich eine Menge Wrapper um den externen Befehl herum schreiben müssen. Hier ist also ein Python-Modul, das wir geschrieben haben und das mit und wenn nicht, ist es sehr flexibel, so dass Sie es leicht erweitern können:
https://github.com/hpcugent/vsc-base/blob/master/lib/vsc/utils/run.py
Es funktioniert nicht eigenständig und erfordert einige unserer anderen Werkzeuge und hat im Laufe der Jahre eine Menge spezialisierter Funktionen erhalten, so dass es für Sie vielleicht kein sofortiger Ersatz ist, aber es kann Ihnen eine Menge Informationen darüber geben, wie die Interna von Python für die Ausführung von Befehlen funktionieren und Ideen, wie man mit bestimmten Situationen umgehen kann.
Nach einigen Recherchen habe ich den folgenden Code, der für mich sehr gut funktioniert. Er gibt sowohl die Standardausgabe als auch den Standardfehler in Echtzeit aus.
stdout_result = 1
stderr_result = 1
def stdout_thread(pipe):
global stdout_result
while True:
out = pipe.stdout.read(1)
stdout_result = pipe.poll()
if out == '' and stdout_result is not None:
break
if out != '':
sys.stdout.write(out)
sys.stdout.flush()
def stderr_thread(pipe):
global stderr_result
while True:
err = pipe.stderr.read(1)
stderr_result = pipe.poll()
if err == '' and stderr_result is not None:
break
if err != '':
sys.stdout.write(err)
sys.stdout.flush()
def exec_command(command, cwd=None):
if cwd is not None:
print '[' + ' '.join(command) + '] in ' + cwd
else:
print '[' + ' '.join(command) + ']'
p = subprocess.Popen(
command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd
)
out_thread = threading.Thread(name='stdout_thread', target=stdout_thread, args=(p,))
err_thread = threading.Thread(name='stderr_thread', target=stderr_thread, args=(p,))
err_thread.start()
out_thread.start()
out_thread.join()
err_thread.join()
return stdout_result + stderr_result
Ihr Code kann Daten verlieren, wenn der Unterprozess beendet wird, während noch Daten zwischengespeichert sind. Lesen Sie stattdessen bis EOF, siehe teed_call()
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.
0 Stimmen
Ich verstehe das nicht, was ist falsch an
import os; os.system('pip list | grep anatome')
? Zumindest kann man damit Piping machen, wie mein Beispiel zeigt. Es ist nicht klar, wie man das mitimport subprocess; subprocess.run(["ls", "-l"])
.