Проблема в том, что pipe
заполнен. Подпроцесс останавливается, ожидая опустошения канала, но затем ваш процесс (интерпретатор Python) завершает работу, прерывая конец канала (отсюда и сообщение об ошибке).
p.wait()
вам не поможет:
Предупреждение Это приведет к взаимоблокировке, если дочерний процесс генерирует достаточно вывода в канал stdout или stderr, так что он блокирует ожидание буфера канала ОС для приема большего количества данных. Используйте communicate()
, чтобы избежать этого.
http://docs.python.org/library/subprocess.html#subprocess.Popen.wait
p.communicate()
вам не поможет:
Примечание Считанные данные буферизируются в памяти, поэтому не используйте этот метод, если размер данных большой или неограниченный.
http://docs.python.org/library/subprocess.html#subprocess.Popen.communicate
p.stdout.read(num_bytes)
вам не помогут:
Предупреждение Используйте communicate()
вместо .stdin.write
, .stdout.read
или .stderr.read
, чтобы избежать взаимных блокировок из-за заполнения других буферов буфера ОС и блокировки дочернего процесса.
http://docs.python.org/library/subprocess.html#subprocess.Popen.stdout
Мораль этой истории в том, что для большого результата subprocess.PIPE
обрекает вас на определенный сбой, если ваша программа пытается прочитать данные (мне кажется, вы должны быть в состоянии поместить p.stdout.read(bytes)
в while p.returncode is None:
, но приведенное выше предупреждение предполагает, что это может привести к тупику).
В документах предлагается заменить трубу-оболочку следующим:
p1 = Popen(["zgrep", "thingiwant", "largefile"], stdout=PIPE)
p2 = Popen(["processreceivingdata"], stdin=p1.stdout, stdout=PIPE)
output = p2.communicate()[0]
Обратите внимание, что p2
получает свой стандартный ввод непосредственно от p1
. Это должно избегать тупиков, но с учетом противоречивых предупреждений выше , кто знает .
В любом случае, если эта последняя часть не работает для вас (хотя должна , однако), вы можете попытаться создать временный файл, записать все данные из первого вызова и затем использовать временный файл как вход для следующего процесса.