Приложения, созданные с использованием буфера ввода и вывода буфера C Standard IO (построена с #include <stdio.h>
) (см. здесь , почему). Библиотека stdio, такая как isatty
, может сказать, что она пишет в канал, а не в TTY, и поэтому она выбирает буферизацию блоков вместо буферизации строк. Данные сбрасываются, когда буфер заполнен, но "hello world\n"
не заполняет буфер, поэтому он не сбрасывается.
В ответе Тимо Хартманн , с использованием * показан обратный путь 1013 * утилита. При этом используется трюк LD_PRELOAD
для замены собственного libstdbuf.so
. Во многих случаях это хорошее решение, но LD_PRELOAD
является своего рода хаком, а не работает в некоторых случаях , поэтому это может не быть общим решением.
Может быть, вы хотите чтобы сделать это непосредственно в Python, и здесь вам могут помочь опции stdlib, вы можете использовать pseudo-tty ( docs py2 , docs py3 ) подключен к stdout вместо трубы . Программа myapplication
должна включить буферизацию строки, что означает, что любой символ новой строки очищает буфер.
from __future__ import print_function
from subprocess import Popen, PIPE
import errno
import os
import pty
import sys
mfd, sfd = pty.openpty()
proc = Popen(["/tmp/myapplication"], stdout=sfd)
os.close(sfd) # don't wait for input
while True:
try:
output = os.read(mfd, 1000)
except OSError as e:
if e.errno != errno.EIO:
raise
else:
print(output)
Обратите внимание, что мы теперь читаем байтов из вывода сейчас, поэтому мы не можем обязательно расшифруйте их прямо сейчас!
См. Обработка вывода подпроцесса с Python в реальном времени для сообщения в блоге, очищающего эту идею. Существуют также сторонние библиотеки для этого, см. ptyprocess .