Пакет подпроцесса Python возвращает сломанную трубу - PullRequest
0 голосов
/ 14 января 2019

Я пытаюсь сделать очень простой пример использования пакета подпроцесса. Скрипт python должен открыть новый процесс и запустить команду read. read команда должна получать входные данные от стандартного ввода через PIPE. Каждый раз, когда я пытаюсь использовать write() и flush(), он говорит:

Traceback (most recent call last):
  File "recorder.py", line 68, in <module>
    p.stdin.flush()
BrokenPipeError: [Errno 32] Broken pipe

Мой код Python выглядит так:

import subprocess
import time


p = subprocess.Popen(
    [
        "read",
    ],
    stdout=subprocess.PIPE,
    stdin=subprocess.PIPE,
    stderr=subprocess.STDOUT,
    shell=True,
    bufsize=1
)

for character in "This is the message!\n":
    p.stdin.write(character.encode("utf-8"))
    time.sleep(0.25)
    p.stdin.flush()

assert p.returncode == 0

Примечание: очень важно отправлять символ за символом (с тайм-аутом сна).

1 Ответ

0 голосов
/ 14 января 2019

Я на самом деле не мог воспроизвести ваш результат *, в моем случае ваш цикл проходит, и он не работает на assert, так как p еще не завершен и не имеет returncode (или, скорее, его значение по-прежнему None в то время). Вставка p.wait() после цикла и перед assert заставит нас проверять результат только после завершения p.

Теперь, за исключением того, что вы видите, оно, скорее всего, указывает, что канал, который вы пытаетесь выполнить flush(), закрыт. Скорее всего из-за того, что процесс уже завершен. Возможно, в вашем случае в этот момент у него уже есть (ненулевой) returncode, что может помочь понять проблему? **


* В моей системе /bin/sh используется subprocess.Popen() с shell=True на самом деле bash. Запустив в вашей системе ["/bin/dash", "-c", "read"], который, предположительно, является оболочкой, вызванной /bin/sh, я также получил сломанный канал.


** Запуск такого тире, похоже, завершается с:

/bin/dash: 1: read: arg count

и вернуть 2.

Что делает этот вопрос еще тире: почему не удается вызвать /bin/dash -c "read" (из python). Похоже, что dash read (в отличие от своего аналога bash) всегда ожидает, что хотя бы одно имя переменной будет считано в качестве аргумента (замените read на read foo).


Полагаю, этот вопрос по питону стал уроком о допущениях и переносимости сценариев оболочки. :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...