6121 Stimmen

Wie kann ich ein Programm ausführen oder einen Systembefehl aufrufen?

Wie rufe ich einen externen Befehl in Python auf, als hätte ich ihn in einer Shell oder Eingabeaufforderung eingegeben?

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 mit import subprocess; subprocess.run(["ls", "-l"]) .

12voto

Hier sind meine zwei Cents: Meiner Meinung nach ist dies die beste Vorgehensweise im Umgang mit externen Befehlen...

Dies sind die Rückgabewerte der Methode execute...

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]

1 Stimmen

Deadlock-Potenzial: Verwenden Sie die .communicate Methode stattdessen

0 Stimmen

Besser noch, vermeiden Sie Popen() und die übergeordnete API verwenden, die jetzt in einer einzigen Funktion zusammengefasst ist subprocess.run()

11voto

Cédric Punkte 156

Ich habe eine kleine Bibliothek geschrieben, die bei diesem Anwendungsfall hilft:

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

Es kann installiert werden mit

pip install citizenshell

Und dann wie folgt verwendet:

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

Sie können die Standardausgabe von der Standardfehlerausgabe 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 der Clou 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, sobald sie verfügbar sind, dank der Option 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

11voto

imagineerThat Punkte 4693

Nur um die Diskussion zu ergänzen: Wenn Sie eine Python-Konsole verwenden, können Sie externe Befehle von IPython . In der IPython-Eingabeaufforderung können Sie Shell-Befehle aufrufen, indem Sie '!' voranstellen. Sie können auch Python-Code mit der Shell kombinieren und die Ausgabe von Shell-Skripten an Python-Variablen zuweisen.

Zum Beispiel:

In [9]: mylist = !ls

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

10voto

rashok Punkte 11608

Aufrufen eines externen Befehls in Python

Ein einfacher Weg, einen externen Befehl aufzurufen, ist die Verwendung von os.system(...) . Und diese Funktion gibt den Exit-Wert des Befehls zurück. Aber der Nachteil ist, dass wir stdout und stderr nicht erhalten werden.

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

Aufrufen 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 abrufen.

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

Aufrufen eines lang laufenden externen Befehls in Python im Hintergrund und Anhalten nach einiger Zeit

Wir können sogar einen lang laufenden Prozess im Hintergrund starten, indem wir subprocess.Popen und beenden Sie ihn nach einiger Zeit, wenn 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]

9voto

David Okwii Punkte 6815

Verwendung:

import subprocess

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

Es gibt eine schöne Ausgabe, mit der man besser arbeiten kann:

['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',
 '']

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