Considerando um software de linha de comando personalizado (por exemplo, loopHelloWorld) que detecta ctrl+C para um bom desligamento. Como canalizar a resposta sem perder o Ctrl+C
?
$ loopHelloWorld
- Ctrl+C to nicely shutdown
Mas com pipe, o pipe mata o software sem um bom desligamento
$ loopHelloWorld |
while IFS= read -r line; do
echo "$line"
done
Exemplo
ping example.com |
while IFS= read -r line; do
echo "$line"
done
Ctrl+Cfaz com que um SIGINT seja enviado a todos os processos no pipeline (pois todos são executados no mesmo grupo de processos que correspondem a esse trabalho de primeiro plano do seu shell interativo).
Então em:
Tanto o processo em execução
loopHelloWorld
quanto aquele que executa o subshell que executa owhile
loop obterão o arquivoSIGINT
.Se
loopHelloWorld
gravar aCtrl+C to nicely shutdown
mensagem em seu stdout, ela também será gravada no pipe. Se isso ocorrer depois que o subshell na outra extremidade já tiver morrido, tambémloopHelloWorld
receberá um SIGPIPE, que você precisará manipular.Aqui, você deve escrever essa mensagem para stderr, pois não é a saída normal do seu comando (embora não se aplique ao
ping
exemplo). Então não passaria pelo cano.Ou você pode fazer com que o subshell executando o loop while ignore o SIGINT para que ele continue lendo a
loopHelloWorld
saída após o SIGINT:isso, no entanto, faria com que o status de saída do pipeline fosse 0 quando você pressionasse Ctrl+C.
Outra opção para esse exemplo específico seria usar
zsh
ouksh93
em vez debash
. Nesses shells, owhile
loop seria executado no processo principal do shell, portanto, não seria afetado pelo SIGINT.Isso não ajudaria,
loopHelloWorld | cat
embora ondecat
eloopHelloWorld
executado no grupo de processos de primeiro plano.Use uma armadilha: