it-swarm-eu.dev

Aufruf eines externen Befehls in Python

Wie kann ich einen externen Befehl aus einem Python-Skript heraus aufrufen (als hätte ich ihn an der Unix-Shell oder der Windows-Befehlszeile eingegeben)?

4038
freshWoWer

Schauen Sie sich das Subprozess-Modul in der Standardbibliothek an:

import subprocess
subprocess.run(["ls", "-l"])

Der Vorteil von subprozess gegenüber system ist, dass es flexibler ist (Sie können stdout, stderr, den "echten" Statuscode, bessere Fehlerbehandlung usw. erhalten).

Die offizielle Dokumentation empfiehlt das subprocess -Modul über das alternative os.system ():

Das subprocess -Modul bietet leistungsfähigere Funktionen, um neue Prozesse zu starten und ihre Ergebnisse abzurufen. Die Verwendung dieses Moduls ist der Verwendung dieser Funktion [ os.system() ] vorzuziehen.

Der Abschnitt " Ersetzen älterer Funktionen durch das Subprozess-Modul " in der Dokumentation subprocess enthält möglicherweise hilfreiche Rezepte.

3905

Hier finden Sie eine Zusammenfassung der Möglichkeiten, externe Programme aufzurufen, sowie deren Vor- und Nachteile:

  1. os.system("some_command with args") übergibt den Befehl und die Argumente an die Shell Ihres Systems. Das ist schön, weil Sie auf diese Weise tatsächlich mehrere Befehle gleichzeitig ausführen und Pipes und Eingabe/Ausgabe-Umleitungen einrichten können. Zum Beispiel: 

    os.system("some_command < input_file | another_command > output_file")  
    

    Das ist zwar praktisch, Sie müssen jedoch manuell mit dem Escape-Verfahren von Shell-Zeichen wie Leerzeichen usw. umgehen. Auf der anderen Seite können Sie auch Befehle ausführen, die einfach Shell-Befehle und keine externen Programme sind. Siehe die Dokumentation .

  2. stream = os.popen("some_command with args") wird dasselbe tun wie os.system, außer dass Sie ein dateiähnliches Objekt erhalten, mit dem Sie auf die Standardein-/ausgabe für diesen Prozess zugreifen können. Es gibt 3 weitere Varianten von popen, die alle mit der E/A etwas anders umgehen. Wenn Sie alles als String übergeben, wird Ihr Befehl an die Shell übergeben. Wenn Sie sie als Liste übergeben, müssen Sie sich keine Sorgen darüber machen, dass irgendetwas entkommt. Siehe die Dokumentation .

  3. Die Popen-Klasse des subprocess-Moduls. Dies ist als Ersatz für os.popen gedacht, hat jedoch den Nachteil, dass es aufgrund seiner umfassenden Eigenschaften etwas komplizierter ist. Zum Beispiel würden Sie sagen:

    print subprocess.Popen("echo Hello World", Shell=True, stdout=subprocess.PIPE).stdout.read()
    

    anstatt: 

    print os.popen("echo Hello World").read()
    

    aber es ist schön, alle Optionen in einer einheitlichen Klasse zu haben, anstatt 4 verschiedene Popen-Funktionen. Siehe die Dokumentation .

  4. Die call-Funktion aus dem subprocess-Modul. Dies ist im Grunde genauso wie die Popen-Klasse und nimmt alle gleichen Argumente an. Sie wartet jedoch einfach, bis der Befehl abgeschlossen ist, und gibt den Rückkehrcode zurück. Zum Beispiel:

    return_code = subprocess.call("echo Hello World", Shell=True)  
    

    Siehe die Dokumentation .

  5. Wenn Sie Python 3.5 oder höher verwenden, können Sie die neue Funktion subprocess.run verwenden. Diese Funktion ähnelt der obigen Beschreibung, ist jedoch noch flexibler und gibt ein CompletedProcess - Objekt zurück, wenn der Befehl ausgeführt wird.

  6. Das os-Modul verfügt auch über alle Fork-, Exec- und Spawn-Funktionen, die Sie in einem C-Programm hätten, aber ich empfehle nicht, sie direkt zu verwenden.

Das subprocess-Modul sollte wahrscheinlich das sein, was Sie verwenden.

Beachten Sie bitte schließlich, dass Sie für alle Methoden, bei denen Sie den endgültigen Befehl übergeben, der von der Shell als String ausgeführt werden soll, die Verantwortung dafür übernehmen müssen. Es gibt schwerwiegende Auswirkungen auf die Sicherheit, wenn einem Teil der Zeichenfolge, den Sie übergeben, nicht vollständig vertraut werden kann. Zum Beispiel, wenn ein Benutzer einen oder einen Teil der Zeichenfolge eingibt. Wenn Sie sich nicht sicher sind, verwenden Sie diese Methoden nur mit Konstanten. Um Ihnen einen Hinweis auf die Auswirkungen zu geben, beachten Sie diesen Code:

print subprocess.Popen("echo %s " % user_input, stdout=PIPE).stdout.read()

und stellen Sie sich vor, der Benutzer gibt "Meine Mutter hat mich nicht geliebt" & rm -rf/ein.

2665
Eli Courtwright

Ich verwende normalerweise:

import subprocess

p = subprocess.Popen('ls', Shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for line in p.stdout.readlines():
    print line,
retval = p.wait()

Mit den stdout-Daten in der Pipe können Sie das tun, was Sie möchten. Sie können diese Parameter (stdout= und stderr=) einfach weglassen und verhalten sich wie os.system().

292
EmmEff

Einige Hinweise zum Trennen des untergeordneten Prozesses vom aufrufenden (Starten des untergeordneten Prozesses im Hintergrund).

Angenommen, Sie möchten eine lange Aufgabe von einem CGI-Skript aus starten, das heißt, der untergeordnete Prozess sollte länger als der CGI-Skript-Ausführungsprozess sein.

Das klassische Beispiel aus dem Subprozess-Modul docs lautet:

import subprocess
import sys

# some code here

pid = subprocess.Popen([sys.executable, "longtask.py"]) # call subprocess

# some more code here

Die Idee hier ist, dass Sie nicht in der Zeile 'call subprocess' warten möchten, bis longtask.py fertig ist. Es ist jedoch nicht klar, was nach der Zeile "etwas mehr Code hier" aus dem Beispiel geschieht.

Meine Zielplattform war Freebsd, aber die Entwicklung fand unter Windows statt, so dass ich das Problem zuerst unter Windows hatte.

Unter Windows (win xp) wird der übergeordnete Prozess erst beendet, wenn longtask.py seine Arbeit beendet hat. Es ist nicht das, was Sie im CGI-Skript wollen. Das Problem ist nicht spezifisch für Python, in der Community PHP sind die Probleme gleich.

Die Lösung besteht darin, DETACHED_PROCESS Process Creation Flag an die zugrunde liegende CreateProcess-Funktion in der Win-API zu übergeben. Falls Sie pywin32 installiert haben, können Sie das Flag aus dem Modul win32process importieren.

DETACHED_PROCESS = 0x00000008

pid = subprocess.Popen([sys.executable, "longtask.py"],
                       creationflags=DETACHED_PROCESS).pid

/ * UPD 2015.10.27 @eryksun merkt in einem Kommentar an, dass das semantisch korrekte Flag CREATE_NEW_CONSOLE (0x00000010) ist * /

Bei freebsd gibt es ein weiteres Problem: Wenn der übergeordnete Prozess abgeschlossen ist, werden auch die untergeordneten Prozesse abgeschlossen. Und das wollen Sie auch nicht im CGI-Skript. Einige Experimente zeigten, dass das Problem darin bestand, sys.stdout zu teilen. Und die Arbeitslösung war folgende:

pid = subprocess.Popen([sys.executable, "longtask.py"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)

Ich habe den Code auf anderen Plattformen nicht überprüft und kenne die Gründe für das Verhalten bei freebsd nicht. Wenn jemand weiß, teilen Sie bitte Ihre Ideen. Beim Googeln beim Starten von Hintergrundprozessen in Python gibt es noch keine Erkenntnisse.

186
newtover
import os
cmd = 'ls -al'
os.system(cmd)

Wenn Sie die Ergebnisse des Befehls zurückgeben möchten, können Sie os.popen verwenden. Dies ist jedoch seit Version 2.6 zugunsten des Moduls subprocess veraltet, auf das andere Antworten bereits eingegangen sind.

113

Ich würde empfehlen, das Subprozess-Modul anstelle von os.system zu verwenden, da es für Sie die Flucht von Shell übernimmt und daher wesentlich sicherer ist: http://docs.python.org/library/subprocess.html

subprocess.call(['ping', 'localhost'])
113
sirwart
import os
os.system("your command")

Beachten Sie, dass dies gefährlich ist, da der Befehl nicht bereinigt wird. Ich überlasse es Ihnen, die relevante Dokumentation zu den Modulen 'os' und 'sys' zu suchen. Es gibt eine Reihe von Funktionen (exec * und spawn *), die ähnliche Aktionen ausführen.

101
nimish

Es gibt viele verschiedene Bibliotheken, mit denen Sie externe Befehle mit Python aufrufen können. Für jede Bibliothek habe ich eine Beschreibung gegeben und ein Beispiel für das Aufrufen eines externen Befehls gezeigt. Der Befehl, den ich als Beispiel verwendet habe, ist ls -l (alle Dateien auflisten). Wenn Sie mehr über eine der Bibliotheken erfahren möchten, habe ich die Dokumentation für jede einzelne aufgelistet und verlinkt.

Quellen:

Dies sind alle Bibliotheken:

Hoffentlich hilft Ihnen das bei der Entscheidung, welche Bibliothek verwendet werden soll :)

subprozess

Mit dem Unterprozess können Sie externe Befehle aufrufen und sie mit ihren Eingabe-/Ausgabe-/Fehler-Pipes (stdin, stdout und stderr) verbinden. Unterprozess ist die Standardeinstellung für die Ausführung von Befehlen, aber manchmal sind andere Module besser.

subprocess.run(["ls", "-l"]) # Run command
subprocess.run(["ls", "-l"], stdout=subprocess.PIPE) # This will run the command and return any output
subprocess.run(shlex.split("ls -l")) # You can also use the shlex library to split the command

os

os wird für "betriebssystemabhängige Funktionalität" verwendet. Es kann auch verwendet werden, um externe Befehle mit os.system und os.popen aufzurufen (Hinweis: Es gibt auch einen Unterprozess.popen). os führt immer die Shell aus und ist eine einfache Alternative für Benutzer, die subprocess.run nicht benötigen oder nicht wissen.

os.system("ls -l") # run command
os.popen("ls -l").read() # This will run the command and return any output

Sch

sh ist eine Unterprozessschnittstelle, mit der Sie Programme aufrufen können, als wären sie Funktionen. Dies ist nützlich, wenn Sie einen Befehl mehrmals ausführen möchten.

sh.ls("-l") # Run command normally
ls_cmd = sh.Command("ls") # Save command as a variable
ls_cmd() # Run command as if it were a function

plumbum

plumbum ist eine Bibliothek für "scriptähnliche" Python-Programme. Sie können Programme wie Funktionen wie in sh aufrufen. Plumbum ist nützlich, wenn Sie eine Pipeline ohne Shell ausführen möchten.

ls_cmd = plumbum.local("ls -l") # get command
ls_cmd() # run command

pexpect

mit pexpect können Sie untergeordnete Anwendungen erzeugen, sie steuern und Muster in ihrer Ausgabe finden. Dies ist eine bessere Alternative zum Unterprozess für Befehle, die unter Unix ein tty erwarten.

pexpect.run("ls -l") # Run command as normal
child = pexpect.spawn('scp foo [email protected]:.') # Spawns child application
child.expect('Password:') # When this is the output
child.sendline('mypassword')

Stoff

fabric ist eine Python 2.5- und 2.7-Bibliothek. Sie können lokale und Remote-Shell-Befehle ausführen. Fabric ist eine einfache Alternative zum Ausführen von Befehlen in einer sicheren Shell (SSH).

fabric.operations.local('ls -l') # Run command as normal
fabric.operations.local('ls -l', capture = True) # Run command and receive output

Gesandter

gesandter ist als "Subprozess für Menschen" bekannt. Es wird als praktischer Wrapper für das subprocess-Modul verwendet.

r = envoy.run("ls -l") # Run command
r.std_out # get output

Befehle

commands enthält Wrapper-Funktionen für os.popen, wurde jedoch aus Python 3 entfernt, da subprocess eine bessere Alternative ist.

Die Bearbeitung basierte auf dem Kommentar von J. F. Sebastian.

63
Tom Fuller

Ich benutze immer fabric für diese Dinge wie:

from fabric.operations import local
result = local('ls', capture=True)
print "Content:/n%s" % (result, )

Dies scheint jedoch ein gutes Werkzeug zu sein: sh (Python-Subprozess-Schnittstelle) .

Schauen Sie sich ein Beispiel an:

from sh import vgdisplay
print vgdisplay()
print vgdisplay('-v')
print vgdisplay(v=True)
60

Überprüfen Sie auch die Python-Bibliothek "pexpect".

Es ermöglicht die interaktive Steuerung von externen Programmen/Befehlen, sogar von ssh, ftp, telnet usw. Sie können nur Folgendes eingeben:

child = pexpect.spawn('ftp 192.168.0.24')

child.expect('(?i)name .*: ')

child.sendline('anonymous')

child.expect('(?i)password')
59
athanassis

Wenn Sie die Ausgabe des Befehls benötigen, den Sie aufrufen, , Können Sie subprocess.check_output (Python 2.7+) verwenden.

>>> subprocess.check_output(["ls", "-l", "/dev/null"])
'crw-rw-rw- 1 root root 1, 3 Oct 18  2007 /dev/null\n'

Beachten Sie auch den Parameter Shell .

Wenn Shell True ist, wird der angegebene Befehl über die Shell ausgeführt. Dies kann nützlich sein, wenn Sie Python hauptsächlich für den verbesserten Steuerungsfluss verwenden, den es über die meisten System-Shells bietet, und dennoch bequemen Zugriff auf andere Shell-Funktionen wie Shell-Pipes, Dateinamens-Platzhalter, Erweiterung der Umgebungsvariablen und Erweiterung von ~ zu Hause eines Benutzers wünschen Verzeichnis. Beachten Sie jedoch, dass Python selbst Implementierungen vieler Shell-ähnlicher Funktionen bietet (insbesondere glob, fnmatch, os.walk(), os.path.expandvars(), os.path.expanduser() und shutil).

53
Facundo Casco

Mit Standard Library

Das Use Unterprozessmodul (Python 3):

import subprocess
subprocess.run(['ls', '-l'])

Dies ist der empfohlene Standardweg. Kompliziertere Aufgaben (Pipes, Ausgabe, Eingabe usw.) können jedoch beim Konstruieren und Schreiben mühsam sein.

Hinweis zur Python-Version: Wenn Sie noch Python 2 verwenden, funktioniert subprocess.call auf ähnliche Weise.

ProTip: shlex.split kann Ihnen helfen, den Befehl für run, call und andere subprocess-Funktionen zu parsen, falls Sie diese nicht in Listenform bereitstellen möchten (oder können!).

import shlex
import subprocess
subprocess.run(shlex.split('ls -l'))

Mit externen Abhängigkeiten

Wenn Sie sich nicht um externe Abhängigkeiten kümmern, verwenden Sie plumbum :

from plumbum.cmd import ifconfig
print(ifconfig['wlan0']())

Es ist der beste subprocess-Wrapper. Es ist plattformübergreifend, das heißt, es funktioniert sowohl auf Windows- als auch auf Unix-ähnlichen Systemen. Installieren Sie mit pip install plumbum.

Eine weitere beliebte Bibliothek ist sh :

from sh import ifconfig
print(ifconfig('wlan0'))

sh hat jedoch die Windows-Unterstützung eingestellt, so dass es nicht mehr so ​​toll ist wie früher. Installieren Sie mit pip install sh.

51
Honza Javorek

Aktualisieren:

subprocess.run ist der empfohlene Ansatz ab Python 3.5 , wenn Ihr Code nicht mit früheren Python Versionen kompatibel sein muss. Es ist konsistenter und bietet eine ähnliche Benutzerfreundlichkeit wie Envoy. (Piping ist allerdings nicht so einfach. Siehe diese Frage für wie .)

Hier sind einige Beispiele aus den Dokumenten .

Führen Sie einen Prozess aus:

>>> subprocess.run(["ls", "-l"])  # doesn't capture output
CompletedProcess(args=['ls', '-l'], returncode=0)

Bei fehlgeschlagenem Lauf erhöhen:

>>> subprocess.run("exit 1", Shell=True, check=True)
Traceback (most recent call last):
  ...
subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1

Capture-Ausgabe:

>>> subprocess.run(["ls", "-l", "/dev/null"], stdout=subprocess.PIPE)
CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0,
stdout=b'crw-rw-rw- 1 root root 1, 3 Jan 23 16:23 /dev/null\n')

Ursprüngliche Antwort:

Ich empfehle es mit Gesandter . Es ist ein Wrapper für den Subprozess, der wiederum soll ersetzen die älteren Module und Funktionen. Envoy ist ein Unterprozess für Menschen.

Beispielverwendung von die Readme :

>>> r = envoy.run('git config', data='data to pipe in', timeout=2)

>>> r.status_code
129
>>> r.std_out
'usage: git config [options]'
>>> r.std_err
''

Pipe Sachen auch herum:

>>> r = envoy.run('uptime | pbcopy')

>>> r.command
'pbcopy'
>>> r.status_code
0

>>> r.history
[<Response 'uptime'>]
45
Joe

So führe ich meine Befehle aus. Dieser Code enthält alles, was Sie so ziemlich brauchen

from subprocess import Popen, PIPE
cmd = "ls -l ~/"
p = Popen(cmd , Shell=True, stdout=PIPE, stderr=PIPE)
out, err = p.communicate()
print "Return code: ", p.returncode
print out.rstrip(), err.rstrip()
45
Usman Khan

Ohne Ausgabe des Ergebnisses:

import os
os.system("your command here")

Mit Ausgabe des Ergebnisses:

import commands
commands.getoutput("your command here")
or
commands.getstatusoutput("your command here")
34
Zuckonit

https://docs.python.org/2/library/subprocess.html

... oder für einen ganz einfachen Befehl:

import os
os.system('cat testfile')
28
Ben Hoffstein

Es gibt auch Plumbum

>>> from plumbum import local
>>> ls = local["ls"]
>>> ls
LocalCommand(<LocalPath /bin/ls>)
>>> ls()
u'build.py\ndist\ndocs\nLICENSE\nplumbum\nREADME.rst\nsetup.py\ntests\ntodo.txt\n'
>>> notepad = local["c:\\windows\\notepad.exe"]
>>> notepad()                                   # Notepad window pops up
u''                                             # Notepad window is closed by user, command returns
27
stuckintheshuck

os.system ist in Ordnung, aber irgendwie veraltet. Es ist auch nicht sehr sicher. Versuchen Sie stattdessen subprocess. subprocess ruft sh nicht direkt auf und ist daher sicherer als os.system.

Weitere Informationen hier .

27
Martin W

Aufruf eines externen Befehls in Python

Verwenden Sie einfach subprocess.run, das ein CompletedProcess-Objekt zurückgibt:

>>> import subprocess
>>> completed_process = subprocess.run('python --version')
Python 3.6.1 :: Anaconda 4.4.0 (64-bit)
>>> completed_process
CompletedProcess(args='python --version', returncode=0)

Warum?

Ab Python 3.5 empfiehlt die Dokumentation subprocess.run :

Die empfohlene Methode zum Aufrufen von Unterprozessen ist die Verwendung der Funktion run () für alle Anwendungsfälle, die damit behandelt werden können. Für weitergehende Anwendungsfälle kann die zugrunde liegende Popen-Schnittstelle direkt verwendet werden.

Hier ist ein Beispiel für die einfachste Verwendung - und genau wie gewünscht:

>>> import subprocess
>>> completed_process = subprocess.run('python --version')
Python 3.6.1 :: Anaconda 4.4.0 (64-bit)
>>> completed_process
CompletedProcess(args='python --version', returncode=0)

run wartet auf den erfolgreichen Abschluss des Befehls und gibt dann ein CompletedProcess-Objekt zurück. Stattdessen kann es TimeoutExpired (wenn Sie ihm ein timeout=-Argument geben) oder CalledProcessError (wenn es fehlschlägt und Sie check=True übergeben) erhöhen.

Wie Sie aus dem obigen Beispiel schließen können, werden stdout und stderr standardmäßig an Ihren eigenen stdout und stderr weitergeleitet.

Wir können das zurückgegebene Objekt überprüfen und den gegebenen Befehl sowie den Rückkehrcode sehen:

>>> completed_process.args
'python --version'
>>> completed_process.returncode
0

Ausgabe erfassen

Wenn Sie die Ausgabe erfassen möchten, können Sie subprocess.PIPE an die entsprechende stderr oder stdout übergeben:

>>> cp = subprocess.run('python --version', 
                        stderr=subprocess.PIPE, 
                        stdout=subprocess.PIPE)
>>> cp.stderr
b'Python 3.6.1 :: Anaconda 4.4.0 (64-bit)\r\n'
>>> cp.stdout
b''

(Ich finde es interessant und etwas uninteressant, dass die Versionsinformationen statt stdout auf stderr gestellt werden.)

Übergeben Sie eine Befehlsliste

Man könnte leicht von der manuellen Eingabe einer Befehlszeichenfolge (wie in der Frage vorgeschlagen wird) zu einer programmgesteuert erstellten Zeichenfolge übergehen. Erstellen Sie keine Strings programmgesteuert. Dies ist ein potenzielles Sicherheitsproblem. Es ist besser anzunehmen, dass Sie der Eingabe nicht vertrauen. 

>>> import textwrap
>>> args = ['python', textwrap.__file__]
>>> cp = subprocess.run(args, stdout=subprocess.PIPE)
>>> cp.stdout
b'Hello there.\r\n  This is indented.\r\n'

Beachten Sie, dass nur args positionell übergeben werden sollte.

Vollständige Unterschrift

Hier ist die tatsächliche Signatur in der Quelle und wie von help(run) gezeigt:

def run(*popenargs, input=None, timeout=None, check=False, **kwargs):

Die popenargs und kwargs werden an den Popen-Konstruktor übergeben. input kann eine Zeichenfolge von Bytes sein (oder Unicode, wenn Kodierung oder universal_newlines=True angegeben wird), die an die Standardeingabe des Unterprozesses geleitet wird.

Die Dokumentation beschreibt timeout= und check=True besser als ich könnte:

Das Timeout-Argument wird an Popen.communicate () übergeben. Wenn der Timeout abläuft, wird der untergeordnete Prozess beendet und gewartet. Das Die TimeoutExpired-Ausnahme wird erneut ausgelöst, nachdem der untergeordnete Prozess über .__ verfügt. beendet.

Wenn check wahr ist und der Prozess mit einem Exit-Code ungleich Null beendet wird, wird ein Die CalledProcessError-Ausnahme wird ausgelöst. Attribute davon Ausnahme enthalten die Argumente, den Exit-Code und stdout und stderr if Sie wurden gefangen genommen.

und dieses Beispiel für check=True ist besser als eines, das ich mir vorstellen könnte:

>>> subprocess.run("exit 1", Shell=True, check=True)
Traceback (most recent call last):
  ...
subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1

Erweiterte Signatur

Hier ist eine erweiterte Signatur, wie in der Dokumentation angegeben:

subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, 
Shell=False, cwd=None, timeout=None, check=False, encoding=None, 
errors=None)

Beachten Sie, dass dies bedeutet, dass nur die Argumentliste positionell übergeben werden soll. Übergeben Sie also die restlichen Argumente als Schlüsselwortargumente.

Popen

Wann stattdessen Popen verwenden? Ich würde kaum einen Use-Case finden, der allein auf den Argumenten basiert. Durch die direkte Verwendung von Popen erhalten Sie jedoch Zugriff auf seine Methoden, einschließlich poll, 'send_signal', 'terminate' und 'wait'.

Hier ist die Popen Signatur wie in der Quelle angegeben. Ich denke, dass dies die präziseste Verkapselung der Informationen ist (im Gegensatz zu help(Popen)):

def __init__(self, args, bufsize=-1, executable=None,
             stdin=None, stdout=None, stderr=None,
             preexec_fn=None, close_fds=_PLATFORM_DEFAULT_CLOSE_FDS,
             Shell=False, cwd=None, env=None, universal_newlines=False,
             startupinfo=None, creationflags=0,
             restore_signals=True, start_new_session=False,
             pass_fds=(), *, encoding=None, errors=None):

Aber informativer ist die Popen-Dokumentation :

subprocess.Popen(args, bufsize=-1, executable=None, stdin=None,
                 stdout=None, stderr=None, preexec_fn=None, close_fds=True,
                 Shell=False, cwd=None, env=None, universal_newlines=False,
                 startupinfo=None, creationflags=0, restore_signals=True,
                 start_new_session=False, pass_fds=(), *, encoding=None, errors=None)

Führen Sie ein untergeordnetes Programm in einem neuen Prozess aus. Unter POSIX verwendet die Klasse os.execvp () - ähnliches Verhalten zum Ausführen des untergeordneten Programms. Unter Windows Die Klasse verwendet die Windows-Funktion CreateProcess (). Die Argumente zu Popen sind wie folgt.

Das Verständnis der verbleibenden Dokumentation zu Popen wird dem Leser als Übung überlassen.

24
Aaron Hall

Es kann so einfach sein:

import os
cmd = "your command"
os.system(cmd)
23

Benutzen:

import os

cmd = 'ls -al'

os.system(cmd)

os - Dieses Modul bietet eine tragbare Möglichkeit, betriebssystemabhängige Funktionen zu verwenden.

Für die weiteren os-Funktionen ist hier die Dokumentation.

23
Priyankara

subprocess.check_call ist praktisch, wenn Sie die Rückgabewerte nicht testen möchten. Bei einem Fehler wird eine Ausnahme ausgelöst.

19
cdunn2001

Ich neige dazu, subprocess zusammen mit shlex zu verwenden (um das Ausweichen von Anführungszeichen zu behandeln)

>>> import subprocess, shlex
>>> command = 'ls -l "/your/path/with spaces/"'
>>> call_params = shlex.split(command)
>>> print call_params
["ls", "-l", "/your/path/with spaces/"]
>>> subprocess.call(call_params)
18
Emil Stenström

os.system erlaubt das Speichern von Ergebnissen nicht. Wenn Sie also Ergebnisse in einer Liste speichern möchten, funktioniert subprocess.call.

17
Saurabh Bangad

Es gibt hier einen weiteren Unterschied, der zuvor nicht erwähnt wurde.

subprocess.Popen führt den <Befehl> als Unterprozess aus. In meinem Fall muss ich die Datei <a> ausführen, die mit einem anderen Programm, <b>, kommunizieren muss. 

Ich habe einen Teilprozess ausprobiert und die Ausführung war erfolgreich. <B> konnte jedoch nicht mit <a> ..__ kommunizieren. Alles ist normal, wenn ich beide vom Terminal aus laufe.

Noch mehr: (HINWEIS: kwrite verhält sich anders als andere Anwendungen. Wenn Sie Folgendes mit Firefox versuchen, werden die Ergebnisse nicht gleich sein.)

Wenn Sie os.system("kwrite") versuchen, bleibt der Programmablauf stehen, bis der Benutzer kwrite beendet. Um das zu überwinden, versuchte ich stattdessen os.system(konsole -e kwrite). Dieses Mal lief das Programm weiter, aber kwrite wurde zum Unterprozess der Konsole.

Jeder, der kwrite ausführt, ist kein Unterprozess (d. H. Er muss im Systemmonitor am linken Rand des Baums erscheinen).

17
Atinc Delican

Ich mag Shell_Command wegen seiner Einfachheit. Es ist auf dem Subprozess-Modul aufgebaut.

Hier ist ein Beispiel aus den Dokumenten:

>>> from Shell_command import Shell_call
>>> Shell_call("ls *.py")
setup.py  Shell_command.py  test_Shell_command.py
0
>>> Shell_call("ls -l *.py")
-rw-r--r-- 1 ncoghlan ncoghlan  391 2011-12-11 12:07 setup.py
-rw-r--r-- 1 ncoghlan ncoghlan 7855 2011-12-11 16:16 Shell_command.py
-rwxr-xr-x 1 ncoghlan ncoghlan 8463 2011-12-11 16:17 test_Shell_command.py
0
16
mdwhatcott

verwenden Sie das OS-Modul

import os
os.system("your command")

z.B

import os
os.system("ifconfig")
15
abhi krishnan

Schamloser Plug, ich habe dafür eine Bibliothek geschrieben: P https://github.com/houqp/Shell.py

Es ist im Grunde ein Wrapper für Popen und Shlex für jetzt. Es unterstützt auch Piping-Befehle, damit Sie Befehle in Python einfacher verketten können. So kannst du Dinge tun wie:

ex('echo hello Shell.py') | "awk '{print $2}'"
14
houqp

Für den Fall, dass Sie einen externen Befehl aufrufen möchten, der unabhängig ausgeführt wird (wird ausgeführt, nachdem das Python-Skript beendet wurde), können Sie eine einfache Warteschlange als task spooler oder den Befehl at verwenden

Ein Beispiel mit Task-Spooler:

import os
os.system('ts <your-command>')

Hinweise zum Task-Spooler (ts): 

  1. Sie können die Anzahl der gleichzeitig ausgeführten Prozesse ("Slots") wie folgt festlegen:

    ts -S <number-of-slots>

  2. Die Installation von ts erfordert keine Administratorrechte. Sie können es mit einer einfachen make aus dem Quellcode herunterladen und kompilieren, es Ihrem Pfad hinzufügen und fertig.

14
Yuval Atzmon

Sie können Popen verwenden und dann den Status der Prozedur überprüfen:

from subprocess import Popen

proc = Popen(['ls', '-l'])
if proc.poll() is None:
    proc.kill()

Check out subprozess.Popen .

13
admire

In Windows können Sie einfach das Modul subprocess importieren und externe Befehle ausführen, indem Sie subprocess.Popen(), subprocess.Popen().communicate() und subprocess.Popen().wait() wie folgt aufrufen:

# Python script to run a command line
import subprocess

def execute(cmd):
    """
        Purpose  : To execute a command and return exit status
        Argument : cmd - command to execute
        Return   : exit_code
    """
    process = subprocess.Popen(cmd, Shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    (result, error) = process.communicate()

    rc = process.wait()

    if rc != 0:
        print "Error: failed to execute command:", cmd
        print error
    return result
# def

command = "tasklist | grep python"
print "This process detail: \n", execute(command)

Ausgabe:

This process detail:
python.exe                     604 RDP-Tcp#0                  4      5,660 K
12
Swadhikar C

Sehr einfachste Möglichkeit, einen Befehl auszuführen und das Ergebnis zurückzuholen:

from commands import getstatusoutput

try:
    return getstatusoutput("ls -ltr")
except Exception, e:
    return None
11
Garfield

So rufen Sie die Netzwerk-ID vom Openstack-Neutron ab

#!/usr/bin/python
import os
netid= "nova net-list | awk '/ External / { print $2 }'"
temp=os.popen(netid).read()  /* here temp also contains new line (\n) */
networkId=temp.rstrip()
print(networkId)

Ausgabe von nova net-list

+--------------------------------------+------------+------+
| ID                                   | Label      | CIDR |
+--------------------------------------+------------+------+
| 431c9014-5b5d-4b51-a357-66020ffbb123 | test1      | None |
| 27a74fcd-37c0-4789-9414-9531b7e3f126 | External   | None |
| 5a2712e9-70dc-4b0e-9281-17e02f4684c9 | management | None |
| 7aa697f5-0e60-4c15-b4cc-9cb659698512 | Internal   | None |
+--------------------------------------+------------+------+

Ausgabe von print (networkId)

27a74fcd-37c0-4789-9414-9531b7e3f126
11
IRSHAD

Hier sind meine zwei Cents: Dies ist aus meiner Sicht die beste Vorgehensweise, wenn Sie mit externen Befehlen umgehen ...

Dies sind die Rückgabewerte der Execute-Methode ...

pass, stdout, stderr = execute(["ls","-la"],"/home/user/desktop")

Dies ist die Ausführungsmethode ...

def execute(cmdArray,workingDir):

    stdout = ''
    stderr = ''

    try:
        try:
            process = subprocess.Popen(cmdArray,cwd=workingDir, stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=1)
        except OSError:
            return [False, '', 'ERROR : command(' + ' '.join(cmdArray) + ') could not get executed!']

        for line in iter(process.stdout.readline, b''):

            try:
                echoLine = line.decode("utf-8")
            except:
                echoLine = str(line)

            stdout += echoLine

        for line in iter(process.stderr.readline, b''):

            try:
                echoLine = line.decode("utf-8")
            except:
                echoLine = str(line)

            stderr += echoLine

    except (KeyboardInterrupt,SystemExit) as err:
        return [False,'',str(err)]

    process.stdout.close()

    returnCode = process.wait()
    if returnCode != 0 or stderr != '':
        return [False, stdout, stderr]
    else:
        return [True, stdout, stderr]
10
Uroš Jarc

Invoke ist ein Python (2.7 und 3.4+) Taskausführungswerkzeug und eine Bibliothek. Es bietet eine saubere High-Level-API zum Ausführen von Shell-Befehlen

>>> from invoke import run
>>> cmd = "pip install -r requirements.txt"
>>> result = run(cmd, hide=True, warn=True)
>>> print(result.ok)
True
>>> print(result.stdout.splitlines()[-1])
Successfully installed invocations-0.13.0 pep8-1.5.7 spec-1.3.1
8
Valery Ramusik

Hier wird ein externer Befehl aufgerufen und die Ausgabe des Befehls zurückgegeben oder gedruckt:

Python Subprozess check_output ist gut für

Führen Sie den Befehl mit Argumenten aus und geben Sie die Ausgabe als Byte-Zeichenfolge zurück.

import subprocess
proc = subprocess.check_output('ipconfig /all')
print proc
7
Rajiv Sharma

Benutzen:

import subprocess

p = subprocess.Popen("df -h", Shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[0]
print p.split("\n")

Es gibt Nice-Ausgabe, mit der einfacher zu arbeiten ist:

['Filesystem      Size  Used Avail Use% Mounted on',
 '/dev/sda6        32G   21G   11G  67% /',
 'none            4.0K     0  4.0K   0% /sys/fs/cgroup',
 'udev            1.9G  4.0K  1.9G   1% /dev',
 'tmpfs           387M  1.4M  386M   1% /run',
 'none            5.0M     0  5.0M   0% /run/lock',
 'none            1.9G   58M  1.9G   3% /run/shm',
 'none            100M   32K  100M   1% /run/user',
 '/dev/sda5       340G  222G  100G  69% /home',
 '']
7
David Okwii

Um die Diskussion noch zu erweitern, können Sie bei Verwendung einer Python-Konsole externe Befehle von IPython aufrufen. In der IPython-Eingabeaufforderung können Sie Shell-Befehle mit dem Präfix '!' Aufrufen. Sie können auch Python-Code mit der Shell kombinieren und die Ausgabe von Shell-Skripts Python-Variablen zuweisen.

Zum Beispiel:

In [9]: mylist = !ls

In [10]: mylist
Out[10]:
['file1',
 'file2',
 'file3',]
7
imagineerThat

Aufruf eines externen Befehls in Python

Eine einfache Möglichkeit, einen externen Befehl aufzurufen, ist os.system(...). Und diese Funktion gibt den Exit-Wert des Befehls zurück. Der Nachteil ist jedoch, dass wir nicht stdout und stderr bekommen.

ret = os.system('some_cmd.sh')
if ret != 0 :
    print 'some_cmd.sh execution returned failure'

Aufruf eines externen Befehls in Python im Hintergrund

subprocess.Popen bietet mehr Flexibilität für die Ausführung eines externen Befehls als die Verwendung von os.system. Wir können einen Befehl im Hintergrund starten und warten, bis er beendet ist. Und danach können wir stdout und stderr bekommen.

proc = subprocess.Popen(["./some_cmd.sh"], stdout=subprocess.PIPE)
print 'waiting for ' + str(proc.pid)
proc.wait()
print 'some_cmd.sh execution finished'
(out, err) = proc.communicate()
print 'some_cmd.sh output : ' + out

Aufruf eines lang laufenden externen Befehls in Python im Hintergrund und nach einiger Zeit zum Stoppen

Wir können sogar einen lang laufenden Prozess mit subprocess.Popen im Hintergrund starten und ihn irgendwann beenden, sobald seine Aufgabe erledigt ist.

proc = subprocess.Popen(["./some_long_run_cmd.sh"], stdout=subprocess.PIPE)
# Do something else
# Now some_long_run_cmd.sh exeuction is no longer needed, so kill it
os.system('kill -15 ' + str(proc.pid))
print 'Output : ' proc.communicate()[0]
6
rashok

Es gibt viele verschiedene Möglichkeiten, externe Befehle in Python auszuführen. Alle haben ihre eigenen Vorzüge und Nachteile.

Meine Kollegen und ich haben Python-Systemverwaltungstools geschrieben. Daher müssen Sie viele externe Befehle ausführen. Manchmal möchten Sie, dass sie blockiert oder asynchron ausgeführt werden, ein Timeout ausführen, jede Sekunde aktualisieren usw.

Es gibt auch verschiedene Möglichkeiten, den Rückgabecode und die Fehler zu behandeln, Sie können die Ausgabe analysieren und neue Eingaben bereitstellen (in einer Art expect ). Oder Sie müssen stdin, stdout und stderr umleiten, um in einem anderen tty zu laufen (z. B. bei Verwendung des Bildschirms).

Sie müssen also wahrscheinlich viele Wrapper um den externen Befehl schreiben. Hier ist also ein Python-Modul, das wir geschrieben haben, das fast alles, was Sie möchten, handhaben kann. Wenn nicht, ist es sehr flexibel, sodass Sie es leicht erweitern können:

https://github.com/hpcugent/vsc-base/blob/master/lib/vsc/utils/run.py

6
Jens Timmerman

Als Beispiel (in 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 für os.system lautet:

import os
os.system('mkdir test.dir')

Die beste Vorgehensweise wäre die Verwendung eines Unterprozesses anstelle von os, wobei .run gegenüber .call bevorzugt wird. Alles, was Sie über den Teilprozess wissen müssen, ist hier . Beachten Sie außerdem, dass die gesamte Python-Dokumentation unter hier zum Download verfügbar ist. Ich habe das PDF als .Zip-Paket heruntergeladen. Ich erwähne das, weil es eine schöne Übersicht über das os-Modul in tutorial.pdf gibt (Seite 81). Außerdem ist es eine maßgebliche Ressource für Python-Codierer.

6
user8468899

Für Python 3.5 und höher wird empfohlen, dass Sie die Funktion run aus dem Subprozess-Modul verwenden. Dadurch wird ein CompletedProcess-Objekt zurückgegeben, aus dem Sie die Ausgabe sowie den Rückgabecode abrufen können.

from subprocess import PIPE, run

command = ['echo', 'hello']
result = run(command, stdout=PIPE, stderr=PIPE, universal_newlines=True)
print(result.returncode, result.stdout, result.stderr)
5

Ich verwende häufig die folgende Funktion für externe Befehle, und dies ist besonders praktisch für lange laufende Prozesse . Die folgende Methode tails verarbeitet die Ausgabe , während ausgeführt wird, und gibt die Ausgabe zurück. löst eine Ausnahme aus , wenn der Prozess fehlschlägt.

Es wird ausgegeben, wenn der Prozess mit der Methode poll () für den Prozess ausgeführt wird.

import subprocess,sys

def exec_long_running_proc(command, args):
    cmd = "{} {}".format(command, " ".join(str(arg) if ' ' not in arg else arg.replace(' ','\ ') for arg in args))
    print(cmd)
    process = subprocess.Popen(cmd, Shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

    # Poll process for new output until finished
    while True:
        nextline = process.stdout.readline().decode('UTF-8')
        if nextline == '' and process.poll() is not None:
            break
        sys.stdout.write(nextline)
        sys.stdout.flush()

    output = process.communicate()[0]
    exitCode = process.returncode

    if (exitCode == 0):
        return output
    else:
        raise Exception(command, exitCode, output)

Sie können es so aufrufen:

exec_long_running_proc(command = "Hive", args=["-f", hql_path])
5
am5

Ein einfacher Weg ist die Verwendung des os-Moduls:

import os
os.system('ls')

Alternativ können Sie auch das Subprozess-Modul verwenden

import subprocess
subprocess.check_call('ls')

Wenn Sie möchten, dass das Ergebnis in einer Variablen gespeichert wird, versuchen Sie Folgendes:

import subprocess
r = subprocess.check_output('ls')
4
amehta

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(" "))
4
andruso

Die Verwendung der Funktion Popen des Moduls subprocess Python ist die einfachste Möglichkeit, Linux-Befehle auszuführen. In diesem Fall gibt die Funktion Popen.communicate() Ihre Befehle aus. Zum Beispiel

import subprocess

..
process = subprocess.Popen(..)   # Pass command and arguments to the function
stdout, stderr = process.communicate()   # Get command output and error
..
4
Asif Hasnain

Es gibt viele Möglichkeiten, einen Befehl aufzurufen.

  • Zum Beispiel:

wenn and.exe zwei Parameter benötigt. In cmd können wir sample.exe Aufrufen und dies verwenden: and.exe 2 3 Und es wird 5 Auf dem Bildschirm angezeigt.

Wenn wir ein Python Skript verwenden, um and.exe Aufzurufen, sollten wir wie folgt vorgehen ..

  1. os.system(cmd,...)

    • os.system(("and.exe" + " " + "2" + " " + "3"))
  2. os.popen(cmd,...)

    • os.popen(("and.exe" + " " + "2" + " " + "3"))
  3. subprocess.Popen(cmd,...)
    • subprocess.Popen(("and.exe" + " " + "2" + " " + "3"))

Es ist zu schwer, also können wir cmd mit einem Leerzeichen verbinden:

import os
cmd = " ".join(exename,parameters)
os.popen(cmd)
4
liuyip

Wenn Sie einen Shell-Befehl von einem Python-Notebook aus aufrufen müssen (wie Jupyter , Zeppelin, Databricks oder Google Cloud Datalab), können Sie einfach das Präfix ! verwenden.

Zum Beispiel,

!ls -ilF
3
dportman

Ich habe eine kleine Bibliothek geschrieben, um bei diesem Anwendungsfall zu helfen:

https://pypi.org/project/citizenshell/

Es kann mit installiert werden 

pip install citizenshell

Und dann wie folgt verwendet:

from citizenshell import sh
assert sh("echo Hello World") == "Hello World"

Sie können stdout von stderr trennen und den Exit-Code wie folgt extrahieren:

result = sh(">&2 echo error && echo output && exit 13")
assert result.stdout() == ["output"]
assert result.stderr() == ["error"]
assert result.exit_code() == 13

Und das Coole ist, dass Sie nicht warten müssen, bis die zugrunde liegende Shell beendet ist, bevor Sie mit der Verarbeitung der Ausgabe beginnen:

for line in sh("for i in 1 2 3 4; do echo -n 'It is '; date +%H:%M:%S; sleep 1; done", wait=False)
    print ">>>", line + "!"

druckt die Zeilen so, wie sie verfügbar sind, dank dem wait = False

>>> It is 14:24:52!
>>> It is 14:24:53!
>>> It is 14:24:54!
>>> It is 14:24:55!

Weitere Beispiele finden Sie unter https://github.com/meuter/citizenshell

3
Cédric

Es gibt zwei wichtige Möglichkeiten, Shell-Befehle mit Python auszuführen. Die beiden unten genannten Beispiele zeigen, wie man mit Python den Namen des aktuellen Arbeitsverzeichnisses (pwd) erhält. Sie können anstelle von pwd jeden anderen Unix-Befehl verwenden. 

1.> 1. Methode: Man kann das Modul os aus Python und die Funktion system () verwenden, um Shell-Befehle in Python auszuführen.

import os
os.system('pwd')

Ausgabe:

/Users/siddharth

1.> 2. Methode: Eine andere Möglichkeit ist die Verwendung des Moduls Subprozess und der Funktion call ()

import subprocess
subprocess.call('pwd')

Ausgabe:

/Users/siddharth
3

Ich würde die folgende Methode "run" empfehlen, die uns dabei helfen wird, STDOUT, STDERR und den Exit-Status als Wörterbuch zu erhalten. Der Aufrufer kann das Wörterbuch mit der 'run'-Methode zurückschicken, um den tatsächlichen Status des Prozesses zu erfahren. 

  def run (cmd):
       print "+ DEBUG exec({0})".format(cmd)
       p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True, Shell=True)
       (out, err) = p.communicate()
       ret        = p.wait()
       out        = filter(None, out.split('\n'))
       err        = filter(None, err.split('\n'))
       ret        = True if ret == 0 else False
       return dict({'output': out, 'error': err, 'status': ret})
  #end
2
Viswesn

Nach einiger Recherche habe ich den folgenden Code, der für mich sehr gut funktioniert. Grundsätzlich werden sowohl stdout als auch stderr in Echtzeit gedruckt. Hoffe, es hilft jemand anderem, der es braucht.

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
2
Jake W

Sultan ist ein neues Paket für diesen Zweck. Bietet einige Details zum Verwalten von Benutzerrechten und zum Hinzufügen hilfreicher Fehlermeldungen.

from sultan.api import Sultan

with Sultan.load(Sudo=True, hostname="myserver.com") as sultan:
  sultan.yum("install -y tree").run()
1
Zach Valenta

Ich habe einen Wrapper geschrieben, um Fehler zu behandeln und die Ausgabe und anderes Material umzuleiten.

import shlex
import psutil
import subprocess

def call_cmd(cmd, stdout=sys.stdout, quiet=False, Shell=False, raise_exceptions=True, use_shlex=True, timeout=None):
    """Exec command by command line like 'ln -ls "/var/log"'
    """
    if not quiet:
        print("Run %s", str(cmd))
    if use_shlex and isinstance(cmd, (str, unicode)):
        cmd = shlex.split(cmd)
    if timeout is None:
        process = subprocess.Popen(cmd, stdout=stdout, stderr=sys.stderr, Shell=shell)
        retcode = process.wait()
    else:
        process = subprocess.Popen(cmd, stdout=stdout, stderr=sys.stderr, Shell=shell)
        p = psutil.Process(process.pid)
        finish, alive = psutil.wait_procs([p], timeout)
        if len(alive) > 0:
            ps = p.children()
            ps.insert(0, p)
            print('waiting for timeout again due to child process check')
            finish, alive = psutil.wait_procs(ps, 0)
        if len(alive) > 0:
            print('process {} will be killed'.format([p.pid for p in alive]))
            for p in alive:
                p.kill()
            if raise_exceptions:
                print('External program timeout at {} {}'.format(timeout, cmd))
                raise CalledProcessTimeout(1, cmd)
        retcode = process.wait()
    if retcode and raise_exceptions:
        print("External program failed %s", str(cmd))
        raise subprocess.CalledProcessError(retcode, cmd)

Man kann es so nennen:

cmd = 'ln -ls "/var/log"'
stdout = 'out.txt'
call_cmd(cmd, stdout)
1
Asav Patel

Das Subprozess-Modul , das oben von Eli beschrieben wurde, ist sehr mächtig, aber die Syntax für den Aufruf eines Sumpf-Standardsystems und das Überprüfen seiner Ausgabe ist unnötig prolix.

Der einfachste Weg, einen Systemaufruf durchzuführen, ist mit dem Befehlsmodul (nur Linux).

> import commands
> commands.getstatusoutput("grep matter alice-in-wonderland.txt")
(0, "'Then it doesn't matter which way you go,' said the Cat.")

Das erste Element im Tupel ist der Rückkehrcode des Prozesses. Das zweite Element ist seine Standardausgabe (und Standardfehler, zusammengeführt).


Die Python-Entwickler haben das Befehlsmodul "abgelehnt", aber das bedeutet nicht, dass Sie es nicht verwenden sollten. Nur, dass sie es nicht mehr entwickeln, was in Ordnung ist, weil es bereits perfekt ist (bei seiner kleinen, aber wichtigen Funktion).

1
Colonel Panic

Da einige Antworten auf frühere Versionen von Python bezogen waren oder os.system-Modul verwendeten, poste ich diese Antwort für Leute wie mich, die subprocess in python 3.5+ verwenden möchten. Das Folgende hat mir den Trick unter Linux gebracht:

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 in der documentation erwähnt, sind PIPE Werte Byte-Sequenzen, und für eine korrekte Darstellung sollte die Decodierung berücksichtigt werden. Für spätere Versionen von Python werden text=True und encoding='utf-8' zu den Warnungen von subprocess.run() hinzugefügt. 

Die Ausgabe des oben genannten Codes ist:

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
1
Farzad Vertigo

Sie können auch subprocess.getoutput() und subprocess.getstatusutput() verwenden, bei denen es sich um Legacy Shell Invocation Functions aus dem veralteten commands -Modul handelt, d. H :

subprocess.getstatusoutput(cmd)

Rückgabe (exitcode, output) der Ausführung von cmd in einer Shell.


subprocess.getoutput(cmd)

Gibt die Ausgabe (stdout und stderr) der Ausführung von cmd in einer Shell zurück.

0
Pedro Lobito

Sie können import und dann den Dateinamen verwenden. Zum Beispiel mit dem eingebauten Modul 'random': import random

0
Chris Oliver

Wenn Sie in den BefehlenNICHTBenutzereingaben verwenden, können Sie diese verwenden

from os import getcwd
from subprocess import check_output
from shlex import quote

def sh(command):
    return check_output(quote(command), Shell=True, cwd=getcwd(), universal_newlines=True).strip()

Und benutze es als

branch = sh('git rev-parse --abbrev-ref HEAD') 

Shell=True wird eine Shell erzeugen, so dass Sie Pipe und solche Shell-Dinge verwenden können sh('ps aux | grep python'). Dies ist sehr praktisch, um fest codierte Befehle auszuführen und die Ausgabe zu verarbeiten. Der universal_lines=True stellt sicher, dass die Ausgabe in einer Zeichenfolge statt binär zurückgegeben wird.

cwd=getcwd() stellt sicher, dass der Befehl mit demselben Arbeitsverzeichnis wie der Interpreter ausgeführt wird. Dies ist praktisch, damit git-Befehle wie im obigen Beispiel für den Namen des git-Zweigs funktionieren.

Einige Rezepte

  • freier Speicher in Megabyte: sh('free -m').split('\n')[1].split()[1]
  • freier Speicherplatz in Prozent sh('df -m /').split('\n')[1].split()[4][0:-1]
  • cPU-Auslastung sum(map(float, sh('ps -ef -o pcpu').split('\n')[1:])

Dies ist jedoch nicht sicher für Benutzereingaben, aus den Dokumenten:

Sicherheitsüberlegungen¶

Im Gegensatz zu einigen anderen popen-Funktionen wird diese Implementierung niemals implizit eine System-Shell aufrufen. Dies bedeutet, dass alle Zeichen, einschließlich Shell-Metazeichen, sicher an untergeordnete Prozesse übergeben werden können. Wenn die Shell explizit über Shell = True aufgerufen wird, muss die Anwendung sicherstellen, dass alle Leerzeichen und Metazeichen in Anführungszeichen gesetzt werden, um Sicherheitsanfälligkeiten bei der Shell-Injektion zu vermeiden.

Bei Verwendung von Shell = True kann die Funktion shlex.quote () verwendet werden, um Whitespace- und Shell-Metazeichen in Zeichenfolgen, die zum Erstellen von Shell-Befehlen verwendet werden sollen, ordnungsgemäß zu umgehen.

Sogar die Verwendung der Funktion shlex.quote() ist gut, um ein wenig paranoid zu bleiben, wenn Benutzereingaben für Shell-Befehle verwendet werden. Eine Möglichkeit besteht darin, einen Hardcode-Befehl zu verwenden, um eine allgemeine Ausgabe vorzunehmen und nach Benutzereingaben zu filtern. Auf jeden Fall wird mit Shell=False sichergestellt, dass nur der Prozess ausgeführt wird, den Sie ausführen möchten, oder es wird ein No such file or directory-Fehler angezeigt.

Außerdem hat dies einen gewissen Einfluss auf die Leistung von Shell=True. Aus meinen Tests geht hervor, dass es ungefähr 20% langsamer ist als Shell=False (Standardeinstellung).

In [50]: timeit("check_output('ls -l'.split(), universal_newlines=True)", number=1000, globals=globals())
Out[50]: 2.6801227919995654

In [51]: timeit("check_output('ls -l', universal_newlines=True, Shell=True)", number=1000, globals=globals())
Out[51]: 3.243950183999914
0
geckos

Wenn Sie ein Python -Shell-Skript schreiben und IPython auf Ihrem System installiert haben, können Sie mit der Knall-Magie einen Befehl in IPython ausführen:

!ls
filelist = !ls
0