RSS Джулия Эванс
Подписаться
Почему трубы иногда «застревают»: буферизация
Буферизация является обычным явлением в терминальных программах для улучшения производительности путем группировки вывода до достижения определенного порогового размера. Это может вызвать проблемы, когда данные добавляются медленно в конвейер, поскольку программы могут буферизовать свой вывод и никогда не записывать его.Grep и подобные программы по умолчанию используют блоковую буферизацию при записи в конвейеры, но используют строковую буферизацию при записи в терминалы, что объясняет, почему команда "tail -f /some/log/file | grep thing1 | grep thing2" может не отображать вывод.Несколько команд буферизуют свой вывод, включая grep, sed, awk, tcpdump и jq, в то время как команды, такие как tail, cat и tee, не делают этого.Языки программирования, такие как C, Python, Ruby и Perl, также могут буферизовать вывод, с различными методами для отключения буферизации.Когда нажимается Ctrl-C на конвейере, вывод программы может быть потерян, поскольку сигнал получен до того, как буфер может быть сброшен.Буферизация также происходит при перенаправлении в файл, но обычно она ведет себя, как ожидается, с содержимым буфера, записанным перед выходом программы.Чтобы избежать буферизации, можно запустить программу, которая быстро завершается, использовать флаг "--line-buffered" с grep, переписать команду с помощью awk, использовать stdbuf или использовать unbuffer, чтобы заставить программу вести себя так, как если бы она писала в терминал.Идеальное решение зависит от конкретной ситуации, с unbuffer, как надежным выбором для его последовательного поведения.Хотя буферизация обычно не является обычной проблемой, она может возникнуть, когда данные медленно добавляются в конвейер. Переменная окружения для отключения буферизации была бы полезна, но ее проектирование и реализация представляют собой сложные задачи.