newbie-python-subprocess: "write error: Broken pipe"
Dank der hilfreichen Anregungen unter:
So, es scheint behoben zu sein, wenn ich
- separate Befehle in einzelne Anrufe zu Popen
- stderr=subprocess.ROHR als argument zu jeder Popen Kette.
Den Neuen code:
import subprocess
import shlex
import logging
def run_shell_commands(cmds):
""" Run commands and return output from last call to subprocess.Popen.
For usage see the test below.
"""
# split the commands
cmds = cmds.split("|")
cmds = list(map(shlex.split,cmds))
logging.info('%s' % (cmds,))
# run the commands
stdout_old = None
stderr_old = None
p = []
for cmd in cmds:
logging.info('%s' % (cmd,))
p.append(subprocess.Popen(cmd,stdin=stdout_old,stdout=subprocess.PIPE,stderr=subprocess.PIPE))
stdout_old = p[-1].stdout
stderr_old = p[-1].stderr
return p[-1]
pattern = '"^85567 "'
file = "j"
cmd1 = 'grep %s %s | sort -g -k3 | head -10 | cut -d" " -f2,3' % (pattern, file)
p = run_shell_commands(cmd1)
out = p.communicate()
print(out)
Original Post:
Ich habe zu lange versucht, ein problem zu lösen, Rohrleitungen einen einfachen Teilprozess.Popen.
Code:
import subprocess
cmd = 'cat file | sort -g -k3 | head -20 | cut -f2,3' % (pattern,file)
p = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE)
for line in p.stdout:
print(line.decode().strip())
Ausgabe für die Datei ~1000 Zeilen Länge:
...
sort: write failed: standard output: Broken pipe
sort: write error
Ausgabe für Datei >241 Linien in der Länge:
...
sort: fflush failed: standard output: Broken pipe
sort: write error
Ausgabe für die Datei <241 Linien in der Länge ist in Ordnung.
Habe ich gewesen das Lesen der Dokumentation und googlen wie verrückt, aber es ist etwas grundlegendes über den subprocess-Modul, das mir fehlt ... vielleicht zu tun mit Puffer. Ich habe versucht p.stdout.flush() und spielt mit dem Puffer der Größe p und.wait(). Ich habe versucht, zu reproduzieren diese mit Befehlen wie "sleep 20; cat moderatefile", aber diese scheint ohne Fehler ausgeführt.
'Neuer code' sehr hilfreich. Die Liebe, die ich verwenden kann, die genau die gleiche befehlspipeline verwendet, wenn ich das testen in der shell. Zwei Vorschläge: 1) stellen Sie plural: run_shell_commands 2) entweder entfernen, auskommentieren oder hinzufügen debug=false um print-Anweisungen innerhalb der Funktion
Danke. Lief in der gleichen broken pipe Problem mit Dateien über einer bestimmten Größe. Ihren code benutzt und es funktioniert wie ein Charme.
nicht setzen die Antwort in deiner Frage, poste es als Antwort statt. btw, der code kann deadlock, wenn jeder der Befehle, die genug produzieren Ausgabe auf stderr. Sie sollte in der Nähe
stdout_old
in das den Eltern nach der übergabe an Popen
zu ermöglichen SIGPIPE upstream (sollte es töten sort
anstatt EPIPE). Siehe auch 'ja' reporting-Fehler mit dem Teilprozess Kommunikation()können Sie den Fehler reproduzieren zu aktuellen Python-Versionen: 2.7 und 3.3?
InformationsquelleAutor mathtick | 2010-11-05
Du musst angemeldet sein, um einen Kommentar abzugeben.
Aus der Rezepte auf Teilprozess docs:
Die Schale war nicht das problem verursacht, aber für einige Grund die Aufteilung der Befehle in der "richtigen" Stelle scheint es zu beheben. Danke!
Sie sollten in der Tat Durchlaufen ROHR statt der Zuordnung eines großen Ausgang, um einige string-Instanz, andernfalls riskieren Sie eine out-of-memory-Ausnahme.
InformationsquelleAutor Paulo Scardine
Dies ist, weil Sie sollten nicht verwenden "shell pipes" in die Befehlszeile übergeben
subprocess.Popen
verwenden, sollten Sie diesubprocess.PIPE
wie diese:Aber ich muss sagen, dass das, was Sie versuchen zu tun, getan werden könnte, in reinem python anstelle von aufrufen eine Reihe von shell-Befehlen.
Die Aufteilung der Befehle scheint es angebracht, auch wenn ich das noch verwenden, shell=True.
InformationsquelleAutor mdeous
Ich habe den gleichen Fehler. Sogar die pipe in einer bash-Skript und ausgeführt, dass anstelle des Rohres in Python. Unter Python würde die broken pipe-Fehler, von bash nicht.
Scheint es mir, dass vielleicht der Letzte Befehl vor den Kopf wirft, ein Fehler wie es ist (die Art) die STANDARDAUSGABE wird geschlossen. Python muss sein Kommissionierung bis auf diese in der Erwägung, dass mit der Schale die Fehler silent. Ich habe mich verändert, meinen code zu konsumieren die gesamte Eingabe und der Fehler ging Weg.
Sinn machen würde-auch mit kleineren Dateien zu arbeiten, da das Rohr wahrscheinlich puffert die gesamte Ausgabe vor dem Kopf beendet. Dies würde erklären, bricht bei größeren Dateien.
z.B. statt einem "head -1' (in meinem Fall war ich wollte nur die erste Zeile), habe ich ein awk 'NR == 1'
Wahrscheinlich gibt es bessere Wege, dies zu tun, je nachdem, wo die 'Kopf -X' tritt in das Rohr.
InformationsquelleAutor Chris Beecroft
Brauchen Sie nicht
shell=True
. Nicht aufrufen die shell. Dies ist, wie ich es tun würde:Sehen, wenn Sie vor dem problem, über die Puffer nach Verwendung dieser?
InformationsquelleAutor user225312
versuchen Sie es mit Kommunikation(), sondern als das Lesen direkt vom stdout.
die python docs sagen:
http://docs.python.org/library/subprocess.html#subprocess.Popen.stdout
InformationsquelleAutor Corey Goldberg