2017-03-11 5 views
2

Ich versuche ein Python-Skript zu schreiben, das als einfache UNIX-Bash-Befehlsshell fungiert. Ich muss alle Ausgaben von meinem Skript blockieren und es zu einer von zwei Dateien umleiten (Fehler oder Ausgabe). Leider bekomme ich beim Ausführen meines Bash-Befehls in einem Verzeichnis die Ausgabe "grep: test_dir: Ist ein Verzeichnis". Dies ist nach dem Umleiten meiner sys.stdout in eine temporäre Datei. Meine Theorie ist, dass Grep selbst die Ausgabe zurücksetzt und diesen Fehler druckt, anstatt einfach die Ausgabe zurückzugeben. Gibt es eine Möglichkeit, alle Ausgaben in eine Datei umzuleiten? Oder missverstehe ich einfach, wie man in Python umleitet?Umleitung der Ausgabe von subprocess.call funktioniert nicht

Hier ist mein aktueller Code.

try: 
    temp_out = sys.stdout 
    sys.stdout = open('./temp.txt', 'w+') 
    output = subprocess.call(['grep', search[0], search[1]]) 
    sys.stdout = temp_out 
except subprocess.CalledProcessError as err: 
    print output 
    err_output = err.returncode 
    print "In error" 

Antwort

0

Von Python doc,

stdout ist für die Ausgabe von Druck() und Ausdruck-Anweisungen und für die Eingabeaufforderungen von Eingang verwendet();

Meine Vermutung ist, es funktioniert nicht für Sub-Prozess.

Eine Möglichkeit, dies zu tun:

p = subprocess.Popen(['grep', search[0], search[1]], stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
out, err = p.communicate() 
sys.stdout.write(out) # you have to decode byte to str if it's Python3 
sys.stderr.write(err) 
+0

Genau das habe ich gebraucht! Es trennt sowohl den Rückgabewert als auch mögliche Fehler auf verschiedene Variablen, die ich manipulieren kann. –

+0

@JacobChesley Eigentlich, wenn Sie nur die Ausgabe und den Fehler des Subprozesses in Dateien umleiten wollen, ist die Lösung von 9000 besser. Wenn du alles umleiten willst, inklusive 'print (...)' in deinem Programm, ist meins besser. – Liteye

+0

In diesem Fall wollte ich alle Ausgaben des Subprozesses einschließlich des Drucks umleiten. Dies war so, dass ich alle Ausgaben in das Format, das ich brauche, manipulieren kann. In diesem Fall war Ihre Lösung, was ich suchte, obwohl 9000 ist eine gute Idee, unter die Haube für zukünftige Bemühungen zu halten. –

0

nicht sys.stdout ersetzen Sie; Öffnen Sie eine normale Datei und übergeben Sie sie als Parameter stdout.

with open('destination.txt', 'w') as redirected_output: 
    p = subprocess.Popen(['ls', '-l'], stdout=redirected_output) 
    p.communicate() 

Nur für mich gearbeitet.

+0

Leider musste ich jede Ausgabe umleiten, die der Subprozess selbst an stdout sendet. Dies leitet nur den Rückgabewert um, den mein Programm bereits getan hat. Der Befehl ls hat dieses Fehlerproblem nicht oder zumindest bei diesem bestimmten Aufruf. –