TAILF(1) User Commands TAILF(1)
NAME
tailf - follow the growth of a log file
SYNOPSIS
tailf [OPTION] file
DESCRIPTION
tailf will print out the last 10 lines of a file and then wait for thefile to grow. It is similar to tail -f but does not access the file
when it is not growing. This has the side effect of not updating the
access time for the file, so a filesystem flush does not occur periodi‐
cally when no log activity is happening.
Кажется примерно разобрался.
Команды в скобках передаются по очереди (как строки из /etc/hosts) и проходят все пайпы, после чего выводится результат. Когда строка поступает на stdin первого грепа он кладет её в буффер и ждет следующие строки и это строка sleep, которая и заставляет его уснуть на 10 секунд. Через 10 секунд, stdin заканчивается (как это понимает греп не совсем ясно) и греп радостно выводит результаты своей работы.
Правильный ответ в том, что stdio по разному буфферизует. При выводе в файл или трубу stdio буферизует по BUFSIZ|PIPE_SIZE (обычно равно PAGE_SIZE), а при выводе в терминал - построчно. Естественно, когда программа завершается, то libc-шный exit вызывает тоже flushall().
Поэтому первый grep на терминал выводит сразу, а в трубу - ждёт.
PS: То что в скобках - это просто инлайновая запись скрипта, можно рассматривать как вызов одной команды «echo_and_sleep».
Значит буферизирует не grep а сам stdio? Но ведь между echo и первым грепом тоже стоит пайп. Разве не должен включаться буфер PIPE_SIZE уже на этом этапе?
Эээ, что по вашему stdio? :) stdio - это набор стандартного высокоуровневого ввода/вывода libc. Именно потому, что он позволяет вот такие фокусы, когда setbuf() разный для разного типа он и высокоуровневый - много о себе мнит, иногда это вредно.
Но ведь между echo и первым грепом тоже стоит пайп.
echo полностью отработало и завершилось, потому в буффер пайпа информация отправлена. Это аналог tailf, в тесте использован sleep для эмуляции, что программа на конце с трубой, в которой пишут — не завершилась, конца файла нет и все остальные программы также ждут завершения файла, но порция вывода отправлена. Потому, если первый grep работает с терминалом, то он выводит строку сразу, если на конце строки есть перевод строки.