Как сделать вывод любой команды оболочки небуферизованным?
Есть ли способ запуска команд оболочки без буферизации вывода?
Например, 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.