Подпроцесс Python: открыть строку чтения перед закрытием stdin

Sep 07 2020
import subprocess as sp

p = sp.Popen("/bin/cat", stdin=sp.PIPE, stdout=sp.PIPE)

p.stdin.write(b"foobaz!\n")
p.stdin.close()
print(p.stdout.readline())

Этот код работает как ожидалось (cat повторяет стандартный ввод, и мы можем прочитать стандартный вывод)

Если закомментировать p.stdin.close(), .readline()блоки на неопределенный срок. .read(1)Вместо этого выполняется тот же вызов . Есть ли способ читать строку с помощью модуля подпроцесса без отправки EOF на стандартный ввод?

Я знаю, что есть другие библиотеки, которые могут решить мою проблему, и я тоже изучаю их. Что касается этого вопроса, мне только любопытно, subprocessесть ли у него такая возможность и как ее реализовать subprocess.

Ответы

1 alani Sep 07 2020 at 12:28

Проблема с буферизацией. Вы можете использовать, bufsize=1если вы также используете universal_newlines=True(хотя тогда вы должны писать строки вместо байтов):

p = sp.Popen("/bin/cat", stdin=sp.PIPE, stdout=sp.PIPE, 
             bufsize=1, universal_newlines=True)
p.stdin.write("foobaz!\n")
print(p.stdout.readline())

Вышеупомянутое протестировано в Python 3.5.2. Примечание. Я отдельно только что прочитал ответ на не связанный с этим вопрос, который предполагает, что в более поздних версиях Python text=Trueэквивалентен universal_newlines=True, но у меня нет более новой установки, чтобы попробовать ее на момент написания.