shell ausführen - Aufruf eines externen Befehls in Python




script subprocess (25)

Mit Standard Library

Das Use- Subprozess-Modul (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: docs.python.org/2/library/shlex.html#shlex.split kann Ihnen helfen, den Befehl auf run , call und andere docs.python.org/2/library/shlex.html#shlex.split zu analysieren, falls Sie diese nicht in Listenform docs.python.org/2/library/shlex.html#shlex.split 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 plumbum , verwenden Sie plumbum :

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

Es ist der beste subprocess Wrapper. Es ist plattformübergreifend, dh es funktioniert sowohl auf Windows- als auch auf Unix-ähnlichen Systemen. Install by pip install plumbum .

Eine andere beliebte Bibliothek ist sh :

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

Sie hat jedoch den Windows-Support eingestellt, so dass sie nicht mehr so ​​toll ist wie früher. Install by pip install sh .

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


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

Wenn Sie die Ergebnisse des Befehls zurückgeben möchten, können Sie os.popen . Dies ist jedoch seit Version 2.6 zugunsten des Subprozess-Moduls veraltet, was andere Antworten gut abgedeckt haben.


Es kann so einfach sein:

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

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

from subprocess import call
call(["ls", "-l"])

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

Die offizielle Dokumentation empfiehlt das Subprozess- Modul über die Alternative os.system ():

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

Der Abschnitt " Ältere Funktionen durch das Unterprozessmodul ersetzen " in der Unterprozessdokumentation kann einige hilfreiche Rezepte enthalten.

Offizielle Dokumentation zum Teilprozessmodul :


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 shell Parameter.

Wenn die Shell True , 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 trotzdem bequemen Zugriff auf andere Shell-Funktionen wie Shell-Pipes, Dateinamens-Platzhalter, Erweiterung der Umgebungsvariablen und die Erweiterung von ~ zu Hause eines Benutzers wünschen Verzeichnis. Beachten Sie jedoch, dass Python selbst Implementierungen vieler shell-ähnlicher Features bietet (insbesondere fnmatch , os.walk() , os.walk() , os.path.expandvars() , os.path.expanduser() und shutil ).


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

Weitere Informationen erhalten Sie here .


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")

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 laufen.

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 PHP-Community sind die Probleme gleich.

Die Lösung besteht darin, das DETACHED_PROCESS-Kennzeichen für die Prozesserstellung an die zugrunde liegende CreateProcess-Funktion in der win-API zu übergeben. Wenn Sie pywin32 installiert haben, können Sie das Flag aus dem Modul win32process importieren. Andernfalls sollten Sie es selbst definieren:

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.


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 run () - Funktion 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. Es kann stattdessen TimeoutExpired (wenn Sie ein timeout= Argument CalledProcessError ) oder CalledProcessError (wenn es fehlschlägt und Sie check=True ) CalledProcessError .

Wie Sie aus dem obigen Beispiel entnehmen 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 das entsprechende stderr oder stdout :

>>> 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 programmgesteuerten 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 sollten.

Vollständige Unterschrift

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

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

Die popenargs und kwargs werden dem Popen Konstruktor übergeben. input kann eine Zeichenfolge von Bytes sein (oder Unicode, wenn encoding oder universal_newlines=True ), 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 das Zeitlimit abgelaufen ist, wird der untergeordnete Prozess beendet und gewartet. Die TimeoutExpired-Ausnahme wird erneut ausgelöst, nachdem der untergeordnete Prozess beendet wurde.

Wenn check den Wert true hat und der Prozess mit einem Exit-Code ungleich Null beendet wird, wird eine CalledProcessError-Ausnahme ausgelöst. Attribute dieser Ausnahme enthalten die Argumente, den Exit-Code und stdout und stderr, wenn sie erfasst wurden.

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 die restlichen Argumente als Schlüsselwortargumente.

Popen

Wann Popenstattdessen verwenden? Ich würde kaum einen Anwendungsfall finden, der allein auf den Argumenten basiert. Direkte Verwendung von Popenwürde Ihnen jedoch Zugriff auf seine Methoden gewähren, einschließlich poll"send_signal", "terminate" und "wait".

Hier ist die PopenSignatur wie in der Quelle angegeben . Ich denke, das ist die präziseste Verkapselung der Informationen (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 PopenDokumentation :

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, um das untergeordnete Programm auszuführen. Unter Windows verwendet die Klasse die Windows-Funktion CreateProcess (). Die Argumente für Popen lauten wie folgt.

Das Verständnis der restlichen Dokumentation ist Popendem Leser als Übung überlassen.


Aktualisieren:

subprocess.run ist der empfohlene Ansatz ab Python 3.5, wenn der Code die Kompatibilität mit früheren Python-Versionen nicht aufrechterhalten muss. Es ist konsistenter und bietet eine ähnliche Benutzerfreundlichkeit wie Envoy. (Piping ist jedoch nicht so einfach. Sehen Sie sich diese Frage an .)

Hier einige Beispiele aus den Dokumenten .

Einen Prozess ausführen:

>>> 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 den https://github.com/kennethreitz/envoy . Es ist ein Wrapper für einen Teilprozess, der die älteren Module und Funktionen ersetzen soll . Gesandter ist Unterprozess für Menschen.

Beispielanwendung aus der 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
''

Rohrzeug auch herum:

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

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

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

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()

Sehen Sie sich subprocess.Popen .


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

Es ermöglicht die interaktive Steuerung externer Programme / Befehle, auch ssh, ftp, telnet usw. Sie können einfach Folgendes eingeben:

child = pexpect.spawn('ftp 192.168.0.24')

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

child.sendline('anonymous')

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

Hier ist 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- / Ausgabeumleitungen einrichten können. Zum Beispiel:

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

    Das ist zwar praktisch, Sie müssen jedoch das Fluchtverhalten von Shell-Zeichen wie Leerzeichen usw. manuell handhaben. Auf der anderen Seite können Sie auch Befehle ausführen, bei denen es sich lediglich um Shell-Befehle handelt und nicht um externe Programme. Siehe die Dokumentation .

  2. stream = os.popen("some_command with args") os.system 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 , hat aber den Nachteil, dass es aufgrund seiner umfassenden os.popen 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 vom subprocess . Dies ist im Grunde genauso wie die Popen Klasse und akzeptiert alle gleichen Argumente. 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. subprocess.run 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- / Spawn-Funktionen, die Sie in einem C-Programm haben würden, aber ich empfehle nicht, sie direkt zu verwenden.

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

Beachten Sie 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 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.


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

subprocess.call(['ping', 'localhost'])

os.systemEs ist nicht möglich, Ergebnisse zu speichern, wenn Sie also Ergebnisse in einer Liste speichern möchten oder etwas subprocess.callfunktioniert.


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 Interface) .

Schauen Sie sich ein Beispiel an:

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

So führe ich meine Befehle aus. Dieser Code hat 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()

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 Funktionen ausführen.


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 ls -l ). 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 (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 so 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

Gesandte

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 enthalten Wrapper-Funktionen für os.popen , wurden jedoch aus Python 3 entfernt, da subprocess eine bessere Alternative ist.

Die Bearbeitung basierte auf JF Sebastians Kommentar.


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

Ein Beispiel mit Task-Spooler:

#!/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)

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. Für die Installation sind tskeine Administratorrechte erforderlich. Sie können es mit einem einfachen makeProgramm herunterladen und kompilieren , es Ihrem Pfad hinzufügen und fertig.


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 in der Pipe können Sie das tun, was Sie möchten. Tatsächlich können Sie diese Parameter einfach weglassen ( stdout= und stderr= ), und es verhält sich wie os.system() .


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}'"

In Windows können Sie nur das Import - subprocessModul und externe Befehle ausgeführt durch den Aufruf subprocess.Popen(), subprocess.Popen().communicate()und subprocess.Popen().wait()wie unten:

+--------------------------------------+------------+------+
| 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:

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

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 finden Sie here die Dokumentation.


Für Get und setzen Arbeitsverzeichnis in Python. Sie können folgenden Code verwenden:

import os cwd = os.getcwd () #for Ruft das Arbeitsverzeichnis ab





python shell command subprocess external