A sintaxe ()
em sh
scripts permite que você inicie um subshell . Você pode pensar em subshells como se as duas linhas seguintes fossem as mesmas:
(echo foo)
sh -c "echo foo"
, ou seja, há um segundo processo dentro de seu script de shell que lida com tudo entre o ()
. Por meio do símbolo pipe (" |
"), a saída padrão dessa sub-rede é conectada à entrada padrão do zenity.
Quando você clicar no botão "Cancelar" na janela zenity, isso fará com que o zenity saia imediatamente. Nesse ponto, a saída padrão da subshell se torna inválida. Isso não mata imediatamente a subcamada; no entanto, quando o próximo comando echo
nessa sub-camada quiser gravar no stdout, ele receberá um sinal SIGPIPE
, significando que o canal ao qual está tentando gravar não possui leitores. O comportamento padrão de um processo em SIGPIPE
é terminar.
Você notará que se você iniciar seu script a partir de um terminal e clicar no botão "cancelar" apenas após uma atualização ser enviada para o zenity, seu prompt do shell não retornará imediatamente; já que o comando sleep ainda está em execução e, como o sono não produz saída, leva um momento até que qualquer saída seja produzida e o SIGPIPE
seja emitido.
Se você não quiser este comportamento, você deve dizer ao shell para não sair ao receber o SIGPIPE:
#!/bin/sh
(
trap -- '' PIPE
echo "10"; sleep 1
# ... etc, your normal script goes here
) |
zenity --progress ...
Esta versão ignorará SIGPIPE
e continuará feliz quando o zenity sair. No entanto, observe que, nesse caso, o botão "cancelar" será muito confuso para o usuário; isso fará com que o zenity saia, mas não fará com que a operação seja abortada. Pode ser melhor apenas passar --no-cancel
.