I have the below script example to handle trap on EXIT and INT signals during some job, and trigger a clean up function that cannot be interrupted
#!/bin/bash
# Our main function to handle some job:
some_job() {
echo "Working hard on some stuff..."
for i in $(seq 1 5); do
#printf "."
printf '%s' "$i."
sleep 1
done
echo ""
echo "Job done, but we found some errors !"
return 2 # to simulate script exit code 2
}
# Our clean temp files function
# - should not be interrupted
# - should not be called twice if interrupted
clean_tempfiles() {
echo ""
echo "Cleaning temp files, do not interrupt..."
for i in $(seq 1 5); do
printf "> "
sleep 1
done
echo ""
}
# Called on signal EXIT, or indirectly on INT QUIT TERM
clean_exit() {
# save the return code of the script
err=$?
# reset trap for all signals to not interrupt clean_tempfiles() on any next signal
trap '' EXIT INT QUIT TERM
clean_tempfiles
exit $err # exit the script with saved $?
}
# Called on signals INT QUIT TERM
sig_cleanup() {
# save error code (130 for SIGINT, 143 for SIGTERM, 131 for SIGQUIT)
err=$?
# some shells will call EXIT after the INT signal
# causing EXIT trap to be executed, so we trap EXIT after INT
trap '' EXIT
(exit $err) # execute in a subshell just to pass $? to clean_exit()
clean_exit
}
trap clean_exit EXIT
trap sig_cleanup INT QUIT TERM
some_job
The trap works properly, clean_tempfiles() cannot be interrupted and the exit code from some_job() is preserved
Now, if I want to redirect the output from some_job() using process substitution, in the last script line:
# - redirect stdout and stderr to stdout_logfile
# - redirect stderr to stderr_logfile
# - redirect both stdout and stderr to terminal
some_job > >(tee -a stdout_logfile) 2> >(tee -a stderr_logfile | tee -a stdout_logfile >&2)
the normal EXIT trap is properly triggered. However, the SIGINT trap is never triggered. Ctr^C cannot be trapped as soon as the last logging line is added
I could workaround it using POSIX sh compliant redirects with temp log fifo pipes, however, I would really have it working with the simpler bash syntax using process substitution
Is this even possible ?