Как сделать вывод любой команды оболочки небуферизованным?

Есть ли способ запуска команд оболочки без буферизации вывода?

Например, hexdump file | ./my_script будет передавать входные данные из hexdump в my_script в буферизованных блоках, а не построчно.

На самом деле я хочу знать общее решение, как сделать любую команду без буферизации?

6 ответов

Решение

AFAIK, вы не можете сделать это без уродливых хаков. Запись в канал (или чтение из него) автоматически включает полную буферизацию, и вы ничего не можете с этим поделать:-(. "Строковая буферизация" (что вам и нужно) используется только при чтении / записи терминала. Уродливые хаки именно так и делают: они подключают программу к псевдотерминалу, чтобы другие инструменты в конвейере считывали / записывали с этого терминала в режиме буферизации строк. Вся проблема описана здесь:

На странице также есть несколько предложений (вышеупомянутые "уродливые хаки"), что делать, то есть использовать unbuffer или трюки с LD_PRELOAD,

Пытаться stdbufВключен в GNU coreutils и, следовательно, практически в любой дистрибутив Linux. Это устанавливает длину буфера для ввода, вывода и ошибки в ноль:

stdbuf -i0 -o0 -e0 command

Команда unbuffer от expect Пакет отключает буферизацию вывода:
Страница Ubuntu: unbuffer - вывод буфера

Пример использования:

unbuffer hexdump file | ./my_script

Вы также можете использовать script Команда, чтобы сделать вывод hexdump с буферизацией строки (hexdump будет работать в псевдо-терминале, который трюки hexdump думать, что он пишет свой стандартный вывод в терминал, а не в канал).

# cf. http://unix.stackexchange.com/questions/25372/turn-off-buffering-in-pipe/
stty -echo -onlcr
script -q /dev/null hexdump file | ./my_script         # FreeBSD, Mac OS X
script -q -c "hexdump file" /dev/null | ./my_script    # Linux
stty echo onlcr

Для решения этой проблемы следует использовать параметры grep или egrep "--line-buffered". никаких других инструментов не требуется.

Для некоторых команд в macOS вы можете использовать NSUnbufferedIO переменная окружения:

Это работает для программ, использующих платформу Apple Foundation, например, встроенные ОС, такие как /usr/sbin/softwareupdateи другие утилиты Swift или Objective-C:

NSUnbufferedIO=YES cmd > output

После некоторого времени поиска в Интернете я нашел именно это для своего варианта использования, поскольку stdbuf а также unbuffer не предустановлены в macOS.

Другие вопросы по тегам