Quando head
termina depois de manipular a primeira linha, ela sai, fechando a outra extremidade do tubo. sort
ainda pode estar tentando escrever mais e gravar em um pipe ou soquete fechado retorna o erro EPIPE. Mas também aumenta o sinal SIGPIPE, matando o processo, a menos que o sinal seja ignorado ou manipulado. Com o sinal ignorado, sort
vê o erro, reclama e sai. Mas se o sinal não for ignorado, ele simplesmente morre, sem deixar uma mensagem de erro.
Ignorar sinais é herdado de processos filhos, para que possamos controlá-los a partir do shell:
$ 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
Eu não tenho idéia porque o cron deixaria o sinal ignorado, a menos que tenha a ver com o systemd, que aparentemente faz com que o SIGPIPE seja ignorado por padrão :
That's not really useful for normal daemons though, and as we try to provide a good, useful execution environment for daemons, we turn this off. Of course, shells and suchlike should turn this on again.
No meu sistema, /lib/systemd/system/cron.service
explicitamente desfaz o padrão para o cron, definindo IgnoreSIGPIPE=false
.