Когда head
завершает обработку первой строки, он выходит, закрывая другой конец канала. sort
может по-прежнему пытаться записать больше, а запись в закрытый канал или сокет возвращает ошибку EPIPE. Но он также вызывает сигнал SIGPIPE, убивая процесс, если только сигнал не проигнорирован или не обработан. Когда сигнал игнорируется, sort
видит ошибку, жалуется и завершает работу. Но если сигнал не проигнорировать, он просто умирает, не оставляя сообщения об ошибке.
Игнорирование сигналов наследуется дочерними процессами, поэтому мы можем управлять им из оболочки:
$ trap - PIPE # set default action for signal
$ sort bigfile | head -1 > /dev/null # no error message
$ trap "" PIPE # ignore the signal
$ sort bigfile | head -1 > /dev/null
sort: write failed: standard output: Broken pipe
sort: write error
Я понятия не имею, почему cron игнорирует сигнал, если только это не связано с systemd, который очевидно делает SIGPIPE по умолчанию игнорируется:
не очень полезно для обычных демонов, и поскольку мы пытаемся предоставить хорошая, полезная среда выполнения для демонов, мы отключаем это. Из конечно, оболочки и тому подобное должны снова включить это.
В моей системе /lib/systemd/system/cron.service
явно отменяет значение по умолчанию для cron, устанавливая IgnoreSIGPIPE=false
.