Como @muru comentou, o problema é que seu script não manipula SIGPIPE
.
As alterações a seguir permitirão que o script termine conforme pretendido:
function signalHandler() {
echo "sig: $1 received ==> exit" >&2 # <--
for i in {1..5}; do
echo "cleanup $i %" >&2 # <--
sleep 1
done
trap SIGINT
kill -INT $$
}
trap signalHandler SIGUSR2
trap signalHandler SIGPIPE # <--
Para manter o exemplo simples, o mesmo manipulador de sinal é usado para manipular SIGPIPE
. A saída echo
do manipulador de sinal é redirecionada para STDERR
, já que STDOUT
obviamente já está corrompido quando o SIGPIPE
é capturado.
Saída:
$ ./script.sh | grep wow
./script.sh: line 16: echo: write error: Broken pipe
sig: received ==> exit
cleanup 1 %
cleanup 2 %
cleanup 3 %
cleanup 4 %
cleanup 5 %
User defined signal 2: 31
As quebras de tubo (primeira mensagem de erro), mas o manipulador de sinal completam antes de script.sh
sair.
Se você quiser ignorar completamente o SIGPIPE
, precisará adicionar um manipulador simulado para o sinal e redirecionar STDERR para a instrução echo
principal para /dev/null
:
function signalHandler2() {
:
}
trap signalHandler SIGUSR2
trap signalHandler2 SIGPIPE
# ...skip...
for i in {1..100000}; do
echo "doing stuff $i %" 2>/dev/null