Я думал, что видел все в 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нуждаются ни в начале, ни в конце файла: они работают с буферами.