Bash – How to ignore interrupts with piped commands

bashinterruptpipe

In the following chain of piped commands, when an interrupt is sent with Ctrl-C, ping is able to print its summary statistics before exiting, as long as tee has the -i (ignore interrupts) flag:

ping -D localhost 2>&1 | tee -a -i ping.log

However, with another command in the chain, ping's summary does not get printed:

ping -D localhost 2>&1 | sed -u 's/^\[\([0-9]*\.[0-9]*\)\]\(.*$\)/echo "[`date -d @\1 +"%Y-%m-%d %H:%M:%S"`] \2"/e' | tee -a -i ping.log

How can the above be made to print the summary?

Does sed have an option to ignore interrupts? In general how can interrupts be handled gracefully with piped commands?

Best Answer

ping -D localhost 2>&1 | (trap '' INT; exec sed -u 's/^\[\([0-9]*\.[0-9]*\)\]\(.*$\)/echo "[`date -d @\1 +"%Y-%m-%d %H:%M:%S"`] \2"/e') | tee -a -i ping.log

Calling trap '' INT tells the shell to ignore SIGINT. The exec is optional but nice to have, since the subshell process is no longer necessary after the trap.

Related Question