«да» с сообщением об ошибке с подпроцессом связи ()

Я использую следующую функцию для запуска команды в Python:

def run_proc(cmd): child = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = child.communicate() returncode = child.returncode return stdout, stderr, returncode 

Он всегда работал нормально, но теперь я пытаюсь использовать программу yes для вывода вывода на stdin. Команда, которую я пытаюсь запустить, следующая:

  • подпроцесс и тип Str не поддерживают API-интерфейс буфера
  • Почему subprocess.Popen () с shell = True работает по-разному в Linux и Windows?
  • Общайтесь с подпроцессом, не дожидаясь завершения подпроцесса в окнах
  • Как определить подпроцесс.Popen () не удалось, когда shell = True
  • Подпроцесс Python получает выход детей в файл и терминал?
  • Стандартный выход подпроцесса трубы к переменной
  •  yes '' | apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" dist-upgrade 

    но я считаю, что его можно заменить общим примером, например:

     yes | head -3 | cat 

    Моя проблема в том, что если я попытаюсь запустить любую команду, у которой есть yes | в нем приведенный выше подпроцесс.Popen будет содержать сообщения об ошибках:

     yes: standard output: Broken pipe yes: write error 

    Для меня кажется, что трубопровод все еще работает, как видно из « yes | head -3 | cat yes | head -3 | cat ответ yes | head -3 | cat : yyy .

    У меня есть следующие вопросы:

    1. Является ли канал да еще работоспособным, хотя да сообщает ошибку?
    2. Как я могу это исправить?

  • Разница между флажками командной строки «проверка» и «интерактивная» в Python
  • Как выполнить многоуровневую CLI в Python?
  • Получить выбранную подкоманду с помощью argparse
  • WindowsError: Доступ запрещается при попытке убить подпроцесс (python)
  • Как реплицировать поведение tee в Python при использовании подпроцесса?
  • Как получить информацию «в реальном времени» из подпроцесса. Открыть в python (2.5)
  • 3 Solutions collect form web for “«да» с сообщением об ошибке с подпроцессом связи ()”

    Проблема заключается в том, что модуль subprocess перед Python 3.2+ не восстанавливает обработчик SIGPIPE по умолчанию . Вот почему вместо этого вы получаете EPIPE записи EPIPE .

    В Python 3.2+

     >>> from subprocess import check_output >>> check_output("yes | head -3", shell=True) b'y\ny\ny\n' 

    yes убит SIGPIPE при выходе head .

    В Python 2:

     >>> from subprocess import check_output >>> check_output("yes | head -3", shell=True) yes: standard output: Broken pipe yes: write error 'y\ny\ny\n' 

    yes полученная EPIPE записи EPIPE . Безопасно игнорировать ошибку. Он передает ту же информацию, что и SIGPIPE .

    Чтобы обойти эту проблему, вы можете эмулировать restore_signals в Python 2 с preexec_fn параметра preexec_fn :

     >>> from subprocess import check_output >>> import signal >>> def restore_signals(): # from http://hg.python.org/cpython/rev/768722b2ae0a/ ... signals = ('SIGPIPE', 'SIGXFZ', 'SIGXFSZ') ... for sig in signals: ... if hasattr(signal, sig): ... signal.signal(getattr(signal, sig), signal.SIG_DFL) ... >>> check_output("yes | head -3", shell=True, preexec_fn=restore_signals) 'y\ny\ny\n' 

    другой вопрос отвечает на вопрос, почему … Я постараюсь дать вам работу

    не могли бы вы сделать что-то вроде

     proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin = subprocess.PIPE) for i in range(10): #send 10 y's time.sleep(1) # 1 second apart proc.stdin.write("y") #you may also need to send a newline ... print proc.communicate() 

    см. ниже (я не беспокоился о задержке, так как голова не очень много делает)

     >>> import subprocess >>> proc = subprocess.Popen("head -3", ... shell = True, ... stdout = subprocess.PIPE, ... stderr=subprocess.PIPE, ... stdin=subprocess.PIPE) >>> for i in range(10): ... proc.stdin.write("y\n") ... >>> proc.communicate() ('y\ny\ny\n', '') 

    Высказывание:

     yes | head -3 

    заставляет head посылать SIGPIPE в « yes только это делается, считывая 3 строки ввода, т. е. посылает сигнал для прекращения yes .

     $ yes | head -3 y y y $ echo "${PIPESTATUS[@]}" 141 0 

    Решение было бы избежать SIGPIPE !

    Python - лучший язык программирования в мире.