Процесс получает SIGPIPE, когда он пытается выполнить запись в канал (именованный или нет) или сокет типа SOCK_STREAM, у которого нет считывателя.
Это вообще желаемое поведение. Типичный пример:
find . | head -n 1
Вы не хотите findпродолжать работать после того, headкак завершили работу (а затем закрыли единственный файловый дескриптор, открытый для чтения по этому каналу).
Команда yesобычно полагается на этот сигнал для завершения.
yes | some-command
Будет писать «y», пока не завершится какая-либо команда.
Обратите внимание, что это происходит не только при выходе из команд, но и тогда, когда все читатели закрыли чтение fd для канала. В:
yes | ( sleep 1; exec <&-; ps -fC yes)
1 2 1 0
Будет 1 (подоболочка), затем 2 (подоболочка + сон), затем 1 (подоболочка), затем 0 fd, считывающих из канала после того, как подоболочка явно закроет свой стандартный ввод, и именно тогда yesполучит SIGPIPE.
Выше, большинство оболочек использовать в pipe(2)то время как ksh93использует socketpair(2), но поведение такое же в этом отношении.
Когда процесс игнорирует SIGPIPE, запись системного вызова ( как правило write, но может быть pwrite, send, splice...) возвращается с EPIPEошибкой. Таким образом, процессы, желающие обработать сломанный канал вручную, обычно игнорируют SIGPIPE и предпринимают действия при ошибке EPIPE.