![SIGPIPE e bash pipefail](https://rvso.com/image/231080/SIGPIPE%20e%20bash%20pipefail.png)
Estou tentando entender melhor o SIGPIPE no Linux.
Eu executei este experimento: { ls -al /tmp/ ; echo "$?" 1>&2 ; } | head
e ele ecoa 141
o que eu entendo ser um código de saída fornecido para processos que saem com SIGPIPE
Anteriormente, eu fazia muito isso sem entender as nuances SIGPIPE
e geralmente executo set -eEuo pipefail
isso, estava tentando entender por que meu o código não falhava o tempo todo devido a canos quebrados... Então fiz esse outro experimento: ( set -o pipefail; { ls -al /tmp/ ; echo "$?" 1>&2 ; } | head; )
e obtive um 0 no eco daquela vez... então, quando pipefail
está ativado, isso significa que SIGPIPE
está suprimido? ou estou entendendo mal o que está acontecendo aqui?
Responder1
ls
pode conseguir gravar toda a sua saída antes de head
sair e quebrar o canal, mesmo que a saída ls
seja maior do que a head
impressa. Isto é porque:
head
pode ler mais do que eventualmente imprimir,- e há um buffer para o tubo de qualquer maneira.
SIGPIPE é acionado pela gravação real em um canal quebrado. Se ls
conseguir escrever toda a sua saída antes de head
sair, não haverá nenhum ato de escrita que acione o SIGPIPE.
Ou ls
pode não conseguir gravar toda a sua saída antes de head
sair. Então ele tentará escrever mais e obterá o SIGPIPE.
Como ls
e head
rodando em paralelo, acho que em geral existe uma condição de corrida. Pode acontecer que alguma saída específica do ls
SIGPIPE acione ou não, aleatoriamente.
Tente com yes
em vez de ls …
:
{ yes ; echo "$?" 1>&2 ; } | head
ou
( set -o pipefail; { yes ; echo "$?" 1>&2 ; } | head; )
yes
gera uma saída que não termina sozinha, portanto após head
as saídas sempre haverá um ato de escrita que aciona o SIGPIPE. Cada um dos comandos acima lhe dará 141
certeza.
Isto não tem nada a ver com pipefail
.