Я пытаюсь обработать прерывание SIGINT/CTRL + C таким образом, что если пользователь случайно нажимает ctrl-c, ему будет предложено сообщение: «Вы хотите выйти? (Y/n)». Если он войдет в «Да», выйдите из сценария. Если нет, то продолжайте с того места, где произошло прерывание. В принципе, мне нужно Ctrl-C работать аналогично Ctrl-Z/SINTSTP, но несколько иначе. Я пробовал различные способы, чтобы добиться этого, но я не получил ожидаемых результатов. Ниже приводится несколько сценариев, которые я пробовал.Как я могу обработать ловушку SIGINT с приглашением пользователя в сценарии оболочки?
Корпус: 1
Сценарий: 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"
Когда я бегу выше сценарий, я получаю ожидаемых результатов.
Выход:
$ 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 !!!
$
Корпус: 2 Я переехал цикл на новый скрипт loop.sh, таким образом, становится play.sh родительский процесс и loop.sh ребенка обработать.
Сценарий: 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
Сценарий: loop.sh
#!/bin/sh
echo "going to sleep"
for i in {1..100}
do
echo "$i"
sleep 3
done
echo "end of sleep"
Выход в данном случае не как ожидалось.
Выход:
$ 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
$
Я понимаю, что когда процесс получает сигнал SIGINT, он распространяется сигнал на все дочерние процессы, таким образом, мой второй случай терпит неудачу. Есть ли способ, которым я могу избежать распространения SIGINT на дочерние процессы и, таким образом, сделать цикл loop.sh так же, как он работал в первом случае?
Примечание:Это всего лишь пример моего фактического применения. Приложение, в котором я работаю, имеет несколько дочерних скриптов в play.sh и loop.sh. Я должен убедиться, что приложение при получении SIGINT не должно заканчиваться, но оно должно запрашивать у пользователя сообщение.
дубликат: http://unix.stackexchange.com/q/240602/4667 –