![](/img/trans.png)
[英]How to handle user prompt/user intervention during shell script execution
[英]How can I handle SIGINT trap with a user prompt in shell script?
我正在嘗試以這樣一種方式處理SIGINT
- Ctrl + C - 中斷,如果用戶不小心按下ctrl-c
,則會提示他一條消息: “你想退出嗎?(y/n)” 。 如果他輸入yes,則退出腳本。 如果否,則從發生中斷的地方繼續。 基本上,我需要Ctrl + C以類似於Ctrl + Z - SIGTSTP
工作 - 但方式略有不同。 我嘗試了各種方法來實現這一點,但我沒有得到預期的結果。 以下是我嘗試過的幾個場景。
情況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我將 for 循環移動到一個新腳本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 的應用程序不應該終止,但它應該提示用戶一條消息。
在您的play.sh
中不要調用新腳本,而是像這樣獲取它:
source ./loop.sh
我想說由於沒有為腳本生成新的子shell,當您退出陷阱時程序流程將繼續。 如果您調用一個新腳本,則陷阱會傳播到子shell,但如果您退出子shell,它將無法返回。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.