Как работает pipeline в *nix системах?
Не получается правильно сформулировать проблему, поэтому на примере:
Пусть head работает так: выводит первые 5 строк из stdin, после чего процесс сразу завершается.
cat some_file.txt | head -5
Читаем содержимое файла some_file.txt. Пусть в нём больше 5 строк. head выводит первые 5 строк и завершается.
Будет ли сам файл some_file.txt читаться до конца после того, как head вывел свои 5 строк и завершился?
Ответы (3 шт):
когда оболочка выполняет команду вида:
$ программа1 | программа2
она запускает два процесса и загружает в них программу1 и программу2, создав предварительно временный сокет, который передаёт первому процессу в качестве stdout, а второму — в качестве stdin:
процесс1 процесс2
stdout → сокет → stdin
если процесс2 внезапно закрывает свой stdin (в вашем примере — прочитав из него пять строк), то процесс1 (при попытке записи в свой stdout) получает сигнал SIGPIPE.
что именно процесс1 будет делать в таком случае — целиком и полностью зависит от того, что в него вложили разработчики программы1. как правило процесс1 тоже благополучно завершает работу.
если, как в вашем примере, процесс1 в этот момент читал информацию из файла, то вполне возможно, что к моменту получения сигнала он уже прочитал очередную «порцию» информации из этого файла. какого именно размера может быть эта «порция», зависит уже не только от реализации самой программы1, но и от операционной системы — как в ней скофигурирована буферизация того устройства, на котором размещается читаемый файл.
Сделал так на более-менее большом файле:
time(cat some_file.txt >/dev/null)
или так:
time(cat some_file.txt | head -5 >/dev/null)
Во втором случае время меньше значительно
Файл не будет читатся до конца если не использовать излишний cat в таких программах как
head
tail
grep
awk
sed
less
ws
Все они могут читать файлы без посреднечества cat. Некоторые (сверяйтесь с документацией) могут прочесть больше однго файла за раз.
Излишняя форма
cat file | head -5
Прямой вызов
head -5 file
$ head --help
Usage: head [OPTION]... [FILE]...
Print the first 10
lines of each FILE to standard output.
With more than one FILE,
precede each with a header giving the file name.
With no FILE, or when FILE is -, read standard input.