Я думал, что видел все в UNIX. Этот вопрос ударил меня из самодовольства. Какой замечательный вопрос!
tail
показывает последние X строк. tail -f
делает то же самое, но по существу в бесконечном цикле: при запуске показывать последние X строк файла, затем использовать магию ОС (например, inotify), отслеживать и показывать новые строки.
Чтобы сделать свою работу, tail
должен быть в состоянии найти конец файла. Если tail
не удается найти конец файла, он не может показать последние X строк, потому что «последний» не определен. Так что жеtail
делать в этом случае? Он ждет, пока не найдет конец файла.
Учти это:
$ chatter() { while :; do date; sleep 1; done; }
$ chatter | tail -f
Похоже, что это никогда не приводит к прогрессу, потому что нет определенного конца файла из chatter
.
Вы получите то же самое поведение, если попросите tail
указать последние строки из канала файловой системы. Рассмотреть возможность:
$ mkfifo test.pipe
$ tail test.pipe
stdbuf
обойти воспринятую проблему было благородной попыткой. Ключевой факт, однако, заключается в том, что буферизация ввода / вывода не является основной причиной: отсутствие определенного конца файла. Если вы посмотрите исходный код tail.c , вы увидите file_lines
комментарий функции:
END_POS - это смещение файла EOF (на единицу больше, чем смещение последнего байта).
и это магия Вам нужен конец файла для tail для работы в любой конфигурации. head
не имеет этого ограничения, ему просто нужен запуск файла (чего может не быть, попробуйте head test.pipe
). Инструменты, ориентированные на потоки, любят sed
и не awk
нуждаются ни в начале, ни в конце файла: они работают с буферами.