newbie-python-subprocess: "write error: Broken pipe"

Dank der hilfreichen Anregungen unter:

So, es scheint behoben zu sein, wenn ich

  1. separate Befehle in einzelne Anrufe zu Popen
  2. 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.

... und p2.kommunizieren() auch funktioniert, aber ich denke, es kann Probleme verursachen, wenn der output groß ist.
'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

Schreibe einen Kommentar