Reputation: 1091
Here is a simplified version of some code I am working on:
#!/bin/bash
term() {
echo ctrl c pressed!
# perform cleanup - don't exit immediately
}
trap term SIGINT
sleep 100 &
wait $!
As you can see, I would like to trap CTRL+C / SIGINT
and handle these with a custom function to perform some cleanup operation, rather than exiting immediately.
However, upon pressing CTRL+C, what actually seems to happen is that, while I see ctrl c pressed!
is echoed as expected, the wait
command is also killed which I would not like to happen (part of my cleanup operation kills sleep
a bit later but first does some other things). Is there a way I can prevent this, i.e. stop CTRL+C input being sent to the wait
command?
Upvotes: 2
Views: 2316
Reputation: 1091
I ended up using a modified version of what @thatotherguy suggested:
#!/bin/bash
term() {
echo ctrl c pressed!
# perform cleanup - don't exit immediately
}
trap term SIGINT
sleep 100 &
pid=$!
while ps -p $pid > /dev/null; do
wait $pid
done
This checks if the process is still running and, if so, runs wait
again.
Upvotes: 2
Reputation: 123490
You can prevent a process called from a Bash script from receiving sigint by first ignoring the signal with trap
:
#!/bin/bash
# Cannot be interrupted
( trap '' INT; exec sleep 10; )
However, only a parent process can wait for its child, so wait
is a shell builtin and not a new process. This therefore doesn't apply.
Instead, just restart the wait
after it gets interrupted:
#!/bin/bash
n=0
term() {
echo "ctrl c pressed!"
n=$((n+1))
}
trap term INT
sleep 100 &
while
wait "$!"
[ "$?" -eq 130 ] # Sigint results in exit code 128+2
do
if [ "$n" -ge 3 ]
then
echo "Jeez, fine"
exit 1
fi
done
Upvotes: 4