Благодаря полезным предложения ниже:новичка питон подпроцесс: «Ошибка записи: Broken труба»
Так что, кажется, фиксируется, когда я
- отдельных команд в индивидуальные вызовы POPEN
- STDERR = subprocess.PIPE в качестве аргумента для каждой цепи Popen.
Новый код:
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)
Оригинал сообщение:
Я потратил слишком много времени, пытаясь решить проблему с пылом простого subprocess.Popen.
Код:
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())
Выход для файла ~ 1000 строк длиной:
...
sort: write failed: standard output: Broken pipe
sort: write error
Выход для файлов> 241 строк в длину:
...
sort: fflush failed: standard output: Broken pipe
sort: write error
Выход для файла < 241 линии в порядке.
Я читал документы и поисковые запросы, как сумасшедшие, но есть что-то принципиальное в модуле подпроцесса, который мне не хватает ... возможно, с буферами. Я пробовал p.stdout.flush() и играл с размером буфера и p.wait(). Я попытался воспроизвести это с помощью команд типа sleep 20; cat averagefile ', но это, кажется, работает без ошибок.
... и p2.communic() также работает, но я думаю, что это может вызвать проблемы, если выход большой. – mathtick
«Новый код» очень полезен. Любовь, что я могу использовать ту же самую командную команду, которую я использовал при тестировании в оболочке. Два предложения: 1) сделать множественное число: run_shell_commands 2) либо удалить, прокомментировать, либо добавить debug = false в операторы печати внутри функции – PeterVermont
Спасибо. Иди в том же сломанном трубке с файлами определенного размера. Используется ваш код, и он работает как шарм. – poof