I am trying to handle SIGINT
(CtrlC) in such a way that if a user accidentally presses ctrl-c, he is prompted with a message, "Do you wish to quit?(y/n)". If he enters yes, then exit the script. If no, then continue from where ever the interrupt occurred. Basically, I need CtrlC to work similar to SIGTSTP
(CtrlZ) but in a slightly different way. I have tried various ways to acheieve this but I didn't get the expected results. Below are few scenario which I tried.
Case: 1
Script: play.sh
#!/bin/sh
function stop()
{
while true; do
read -rep $'\nDo you wish to stop playing?(y/n)' yn
case $yn in
[Yy]* ) echo "Thanks for playing !!!"; exit 1;;
[Nn]* ) break;;
* ) echo "Please answer (y/n)";;
esac
done
}
trap 'stop' SIGINT
echo "going to sleep"
for i in {1..100}
do
echo "$i"
sleep 3
done
echo "end of sleep"
When I run the above script, I get the expected results.
Output:
$ play.sh
going to sleep
1
^C
Do you wish to stop playing?(y/n)y
Thanks for playing !!!
$ play.sh
going to sleep
1
2
^C
Do you wish to stop playing?(y/n)n
3
4
^C
Do you wish to stop playing?(y/n)y
Thanks for playing !!!
$
Case: 2
I moved the for
loop to a new script loop.sh
, thus play.sh
becomes the parent process and loop.sh
the child process.
Script: play.sh
#!/bin/sh
function stop()
{
while true; do
read -rep $'\nDo you wish to stop playing?(y/n)' yn
case $yn in
[Yy]* ) echo "Thanks for playing !!!"; exit 1;;
[Nn]* ) break;;
* ) echo "Please answer (y/n)";;
esac
done
}
trap 'stop' SIGINT
loop.sh
Script: loop.sh
#!/bin/sh
echo "going to sleep"
for i in {1..100}
do
echo "$i"
sleep 3
done
echo "end of sleep"
Output in this case is not as expected.
Output:
$ play.sh
going to sleep
1
2
^C
Do you wish to stop playing?(y/n)y
Thanks for playing !!!
$ play.sh
going to sleep
1
2
3
4
^C
Do you wish to stop playing?(y/n)n
$
I understand that when a process receives a SIGINT
signal, it propagates the signal to all the child processes, thus my 2nd case is failing. Is there any way that I can avoid SIGINT
being propagated to child processes and thus make the loop.sh
work exactly the way it worked in the 1st case?
Note: This is just an example of my actual application. The application I am working on has several child scripts in play.sh
and loop.sh
. I should make sure that the application on receiving SIGINT
, should not terminate but it should prompt the user with a message.