Внедрение стандартного вывода другой программы для небуферизации с использованием Python

Сценарий python контролирует внешнее приложение в Linux, передает входные данные через канал во внешние приложения stdin и считывает выходные данные через канал из внешних приложений stdout.

Проблема в том, что записи в каналы буферизуются блоком, а не по строке, и поэтому задержки возникают до того, как контрольный скрипт получает данные, выводимые, например, printf во внешнем приложении.

Внешнее приложение не может быть изменено для добавления явных вызовов fflush (0).

Как можно использовать модуль pty стандартной библиотеки python с модулем подпроцесса для достижения этого?

7 Solutions collect form web for “Внедрение стандартного вывода другой программы для небуферизации с использованием Python”

Выполнение этого возможно, но единственное решение, о котором я могу думать, довольно запутанное, не переносное и, вероятно, чревато проблематичными деталями. Вы можете использовать LD_PRELOAD, чтобы заставить внешнее приложение загружать динамическую библиотеку, которая содержит конструктор, который вызывает setvbuf для unbuffer stdout. Вероятно, вы также захотите обернуть setvbuf в библиотеке, чтобы приложение явно не буферизовало свой собственный stdout. И вы захотите обернуть fwrite и printf, чтобы они смывались при каждом вызове. Запись .so для предварительной загрузки приведет вас за пределы python.

Вы можете использовать PTY, чтобы решить эту проблему:

  • Создание пары pty master / slave;
  • Подключение stdin, stdout и stderr дочернего процесса к ведомому устройству pty;
  • Чтение и запись в master-файл pty в родителе.

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

Обратите внимание на то, что у хорошо установленной команды, такой как файл, есть опция (-n), которая заставляет ее явно вывести свой вывод. Это необходимо при использовании файла в режиме, в котором он считывает имена входных файлов из канала и печатает обнаруженный тип. Поскольку в этом режиме файловая программа не завершает работу, результат в противном случае не отображается.

Рассмотрите это на более низком уровне: буферизация вывода просто означает, что выполнение write() в буферизованном потоке копирует данные в буфер памяти в памяти, пока буфер не заполнится или (обычно) до тех пор, пока не будет найдена строка. Затем часть буфера до переполнения или перевода строки записывается write() n в базовый дескриптор файла системного уровня (который может быть файлом, трубой, сокетом, …).

Я не понимаю, как вы собираетесь убедить эту программу сбросить свой буфер извне.

Стоит отметить, что некоторые программы только буферизуют их выход, когда думают, что это не будет «реальным пользователем» (т. Е. Tty). Когда они обнаруживают, что их вывод считывается другой программой, они буферизуют.

Эмуляция tty является одной из вещей, которые Expect делает для автоматизации других процессов.

Существует чистая реализация Python Expect , но я не знаю, насколько хорошо она обрабатывает эмуляцию tty.

Ответ на этот вопрос может помочь:

Python Запустить подпроцесс демона и прочитать stdout

Кажется, решает ту же проблему.

Этот вопрос немного устарел , но я думаю, что теперь ваша проблема может быть решена с помощью подпроцесса для вызова stdbuf с помощью команды, которую вы хотите выполнить.

Попробуйте запустить интерпретатор Python с аргументом -u:

 python -u myscript.py 

Это заставляет Python использовать небуферизованный stdin / stdout, который может вам помочь.

  • Python. Перенаправить stdout в сокет
  • Отменить stdout / stderr тестируемой программы, но сохранить unittest output
  • передача \ n (новая строка) в аргументе stdout throught sys
  • Как перенаправить stdout в текстовый виджет Tkinter
  • Python 2.x - записать двоичный вывод в stdout?
  • Как перенаправить stdout для подпроцесса?
  • Выход Unicode в stdout Python при запуске из cmd.exe
  • Перенаправление подпроцесса stdout
  • Python - лучший язык программирования в мире.