1464 Stimmen

Ausführen des Shell-Befehls und Erfassen der Ausgabe

Ich möchte eine Funktion schreiben, die ein Shell-Kommando ausführt und seine Ausgabe als String zurückgibt, unabhängig davon, ob es sich um eine Fehler- oder Erfolgsmeldung handelt. Ich möchte nur das gleiche Ergebnis erhalten, das ich mit der Befehlszeile erhalten hätte.

Was wäre ein Codebeispiel, das so etwas tun würde?

Zum Beispiel:

def run_command(cmd):
    # ??????

print run_command('mysqladmin create test -uroot -pmysqladmin12')
# Sollte etwas wie folgt ausgeben:
# mysqladmin: CREATE DATABASE failed; error: 'Can't create database 'test'; database exists'

6voto

Hier eine Lösung, die funktioniert, wenn Sie den Output während des Prozesses drucken möchten oder nicht.


Ich habe auch das aktuelle Arbeitsverzeichnis hinzugefügt, es war für mich mehr als einmal nützlich.


Ich hoffe, die Lösung wird jemandem helfen :).

import subprocess

def run_command(cmd_and_args, print_constantly=False, cwd=None):
"""Führt einen Systembefehl aus.

:param cmd_and_args: der Befehl, der mit oder ohne Pipe (|) ausgeführt werden soll.
:param print_constantly: Wenn True, wird der Output kontinuierlich protokolliert, bis der Befehl endet.
:param cwd: das aktuelle Arbeitsverzeichnis (das Verzeichnis, aus dem heraus Sie den Befehl ausführen möchten)
:return: - ein Tupel, das den Rückgabecode, den stdout und den stderr des Befehls enthält
"""
output = []

process = subprocess.Popen(cmd_and_args, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd)

while True:
    next_line = process.stdout.readline()
    if next_line:
        output.append(str(next_line))
        if print_constantly:
            print(next_line)
    elif not process.poll():
        break

error = process.communicate()[1]

return process.returncode, '\n'.join(output), error

6voto

George Chalhoub Punkte 12519

Aus irgendeinem Grund funktioniert dieser Code in Python 2.7 und Sie müssen nur os importieren!

import os 

def bash(command):
    output = os.popen(command).read()
    return output

print_me = bash('ls -l')
print(print_me)

5voto

Neo li Punkte 320

According to @senderle, wenn du wie ich Python3.6 verwendest:

def sh(cmd, input=""):
    rst = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, input=input.encode("utf-8"))
    assert rst.returncode == 0, rst.stderr.decode("utf-8")
    return rst.stdout.decode("utf-8")

sh("ls -a")

Wird genau so funktionieren, als würdest du den Befehl in Bash ausführen

5voto

Ethan Strider Punkte 7091

Wenn Sie einen Shell-Befehl auf mehrere Dateien ausführen müssen, hat das bei mir funktioniert.

import os
import subprocess

# Definieren Sie eine Funktion zum Ausführen von Befehlen und zum Erfassen von stdout zeilenweise
# (Modifiziert von Vartecs Lösung, weil es nicht alle Zeilen gedruckt hat)
def runProcess(exe):    
    p = subprocess.Popen(exe, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    return iter(p.stdout.readline, b'')

# Alle Dateinamen im Arbeitsverzeichnis abrufen
for filename in os.listdir('./'):
    # Dieser Befehl wird auf jede Datei ausgeführt
    cmd = 'nm ' + filename

    # Führen Sie den Befehl aus und erfassen Sie die Ausgabe zeilenweise.
    for line in runProcess(cmd.split()):
        # Führende und abschließende Leerzeichen entfernen
        line.strip()
        # Die Ausgabe aufteilen 
        output = line.split()

        # Filtern Sie die Ausgabe und geben Sie relevante Zeilen aus
        if len(output) > 2:
            if ((output[2] == 'set_program_name')):
                print filename
                print line

Bearbeitung: Habe gerade Max Perssons Lösung mit J.F. Sebastians Vorschlag gesehen. Habe das gleich umgesetzt.

2voto

tushar Punkte 371

Verbesserung für besseres Protokollieren.
Für bessere Ausgaben können Sie einen Iterator verwenden. Von unten erhalten wir bessere

from subprocess import Popen, getstatusoutput, PIPE
def shell_command(cmd):
    result = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE)

    output = iter(result.stdout.readline, b'')
    error = iter(result.stderr.readline, b'')
    print("##### Ausgabe ###")
    for line in output:
        print(line.decode("utf-8"))
    print("###### Fehler ########")
    for line in error:
        print(error.decode("utf-8")) # Bytes in Str umwandeln

    status, terminal_output = run_command(cmd)
    print(terminal_output)

shell_command("ls") # Dies zeigt alle Dateien & Ordner im Verzeichnis an

Anderes Verfahren unter Verwendung von getstatusoutput (Einfach zu verstehen)

from subprocess import Popen, getstatusoutput, PIPE

status_Code, output = getstausoutput(command)
print(output) # Dies gibt die Terminalausgabe aus

# status_code, output = getstatusoutput("ls") # Dies druckt alle Dateien & Ordner aus, die im Verzeichnis verfügbar sind

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