Процесс получает 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.