Dzięki pomocnych wskazówek poniżej:początkujących pyton podproces: „błąd zapisu: Broken pipe”
Więc wydaje się być ustalona, kiedy
- oddzielne polecenia w poszczególnych wezwań do POPEN
- stderr = subprocess.PIPE jako argument dla każdego łańcucha Popen.
nowy kod:
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:
spędziłem zbyt długo stara się rozwiązać problem orurowanie prostą subprocess.Popen.
Kod:
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())
wyjścia dla plików ~ 1000 linii o długości:
...
sort: write failed: standard output: Broken pipe
sort: write error
wyjścia dla plików> 241 linii o długości:
...
sort: fflush failed: standard output: Broken pipe
sort: write error
wyjście do pliku < 241 długość linii jest w porządku.
Przeczytałem dokumentację i szukałem czegoś jak szalonego, ale jest coś fundamentalnego w module podprocesu, którego mi brakuje ... może z buforami. Próbowałem p.stdout.flush() i grając z rozmiarem bufora i p.wait(). Próbowałem odtworzyć to za pomocą poleceń takich jak "sleep 20; cat moderatefile ", ale wydaje się, że działa bez błędu.
... i p2.communicate() również działa, ale myślę, że może to spowodować problemy, jeśli wyjście jest duże. – mathtick
"Nowy kod" jest bardzo pomocny. Uwielbiam, że mogę użyć dokładnie tego samego polecenia wypróbowanego, którego użyłem podczas testowania w powłoce. Dwie sugestie: 1) tworzą liczbę mnogą: run_shell_commands 2) usuń, skomentuj lub dodaj debug = false wokół instrukcji print wewnątrz funkcji – PeterVermont
Dzięki. Wystąpił ten sam problem z potokami z plikami przekraczającymi pewien rozmiar. Użyłeś swojego kodu i działa jak urok. – poof