Python заменяет оболочку конвейера - PullRequest
0 голосов
/ 12 июня 2018

Пример , найденный здесь

output=`dmesg | grep hda`

, становится:

p1 = Popen(["dmesg"], stdout=PIPE)
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
p1.stdout.close()  # Allow p1 to receive a SIGPIPE if p2 exits.
output = p2.communicate()[0]

Как расширить его до трехпроцессного конвейера?

Кроме того, я не смог найти, что именно делает p1.stdout.close ()?Что делать, если p1 работает долго?будет ли он ждать завершения p1, прежде чем применять close ()?

Должен ли close () прийти перед связью ()?

Правильно ли я понимаю, что перед вызовом connect () конвейернастроен, но "на удержании"?Или, скорее, каждый процесс запускается параллельно сразу же, но те, которые требуют ввода от stdin, блокируются до тех пор, пока не будет вызван connect ()?


Рассмотрим:

output=`dmesg | grep hda | grep bla`

Может быть что-токак это:

p1 = Popen(["dmesg"], stdout=PIPE)
p1.stdout.close()  # Allow p1 to receive a SIGPIPE if p2 exits.

p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
p2.stdout.close()  # Allow p2 to receive a SIGPIPE if p3 exits.

p3 = Popen(["grep", "bla"], stdin=p2.stdout, stdout=PIPE)

output = p3.communicate()[0]

(приведенный выше сбой с ValueError: I/O operation on closed file в текущей форме)

Этот не выдает ошибку, но так как я не понимаю закрытия (), это может быть настройка для Doom через некоторое время:

p1 = Popen(["dmesg"], stdout=PIPE)
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)

p1.stdout.close()  # Allow p1 to receive a SIGPIPE if p2 exits.

p3 = Popen(["grep", "bla"], stdin=p2.stdout, stdout=PIPE)

p2.stdout.close()  # Allow p2 to receive a SIGPIPE if p3 exits.

output = p3.communicate()[0]

Или это:

p1 = Popen(["dmesg"], stdout=PIPE)
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
p3 = Popen(["grep", "bla"], stdin=p2.stdout, stdout=PIPE)

p1.stdout.close()  # Allow p1 to receive a SIGPIPE if p2 exits.
p2.stdout.close()  # Allow p2 to receive a SIGPIPE if p3 exits.

output = p3.communicate()[0]

1 Ответ

0 голосов
/ 12 июня 2018

В соответствии с пунктом 17.1.4.2 документации по питону https://docs.python.org/2/library/subprocess.html, вызов p1.stdout.close () после запуска p2 важен для того, чтобы p1 получил SIGPIPE, если p2 выходит до p1.Аналогично, p2.stdout.close () должен вызываться и после запуска p3.

Как обрабатывать сломанную трубу (SIGPIPE) в python? объясняет, как обрабатывать сломанную трубу(SIGPIPE).

...