Как работает pipeline в *nix системах?

Не получается правильно сформулировать проблему, поэтому на примере:

Пусть head работает так: выводит первые 5 строк из stdin, после чего процесс сразу завершается.

cat some_file.txt | head -5

Читаем содержимое файла some_file.txt. Пусть в нём больше 5 строк. head выводит первые 5 строк и завершается.

Будет ли сам файл some_file.txt читаться до конца после того, как head вывел свои 5 строк и завершился?


Ответы (3 шт):

Автор решения: aleksandr barakin

когда оболочка выполняет команду вида:

$ программа1 | программа2

она запускает два процесса и загружает в них программу1 и программу2, создав предварительно временный сокет, который передаёт первому процессу в качестве stdout, а второму — в качестве stdin:

процесс1         процесс2
 stdout → сокет → stdin

если процесс2 внезапно закрывает свой stdin (в вашем примере — прочитав из него пять строк), то процесс1 (при попытке записи в свой stdout) получает сигнал SIGPIPE.

что именно процесс1 будет делать в таком случае — целиком и полностью зависит от того, что в него вложили разработчики программы1. как правило процесс1 тоже благополучно завершает работу.

если, как в вашем примере, процесс1 в этот момент читал информацию из файла, то вполне возможно, что к моменту получения сигнала он уже прочитал очередную «порцию» информации из этого файла. какого именно размера может быть эта «порция», зависит уже не только от реализации самой программы1, но и от операционной системы — как в ней скофигурирована буферизация того устройства, на котором размещается читаемый файл.

→ Ссылка
Автор решения: nikolas

Сделал так на более-менее большом файле:

time(cat some_file.txt >/dev/null)

или так:

time(cat some_file.txt | head -5 >/dev/null)

Во втором случае время меньше значительно

→ Ссылка
Автор решения: Hellseher

Файл не будет читатся до конца если не использовать излишний 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.
→ Ссылка