I have a shell script (example.sh
) in which I am creating and allocating (mounting) space in the /media
directory and I'm copying some files there for faster processing.
ram_disk=/media/ram_disk
sudo mount -t tmpfs -o size=100000000 tmpfs "$ram_disk"
sudo cp "$some_random_file" "$ram_disk"
At the end of this shell script, I unmount and delete $ram_disk
as follows-
sudo umount "$ram_disk"
cd /media
sudo rm -r "$ram_disk"
So that CTRL C
interruptions doesn't create problems, I've added a trap
handler at the start (first lines) of the shell script
ctrlc_count=0
function no_sigint {
let ctrlc_count
if [[ $ctrlc_count == 1 ]]; then
echo "Aborting process"
if [ -d "$ram_disk" ]; then
sudo umount "$ram_disk"
cd /media
sudo rm -r "$ram_disk"
else
:
fi
fi
}
trap no_sigint SIGINT
And if no SIGINT
is supplied, variable ctrlc_count
remains 0
and ram_disk
is removed normally at the end of the shell script (last lines)-
if [[ $ctrlc_count == 0 ]]; then
sudo umount "$ram_disk"
cd /media
sudo rm -r "$ram_disk"
fi
This has been working fine so far. However, if I pipe the shell script with another bash command and supply SIGINT
, the trap handler does not work -
bash example.sh | head -10
bash example.sh | tail -10
Using CTRL C
in the above scenario does not remove $ram_disk
.
Any suggestions on how can I improve my code to take piping commands into consideration? Thank you.
CodePudding user response:
Trap EXIT
instead of SIGINT
.
SIGINT refers to an interrupt signal, generated by Ctrl-C by default. That's not the only condition that can end a script.
EXIT
commands will run when the script exits regardless of the reason - unless it's an uncatchable signal such as SIGKILL.
CodePudding user response:
Trapping EXIT
is a good solution, but it doesn't explain the behavior you're seeing.
When you use ctrl-C
to send SIGINT to the foreground process group, the tail/head
gets terminated. The SIGINT trap in the bash script is executed, but in bash echo
is a builtin so the echo "Aborting process"
generates a SIGPIPE to the script which is uncaught and the script immediately terminates. Writing error messages/diagnostics to stderr isn't just a good idea, it saves your from this bug. The "correct" solution is to trap EXIT, but a (potentially) easier approach is to use echo 'Aborting process' >&2
.