我需要帮助来准确了解SIGINT如何在Shell脚本的主流程和该脚本内的函数调用之间传播。对于我的脚本,我有一个主菜单,该菜单接受用户输入并基于该输入调用子功能。子功能与用户交互。
我的目标如下:
我看到的行为是我可以在主菜单内或从子功能内按ctrl + c,并且第一次可以按预期运行,但是所有后续ctrl + c信号都将被忽略。
我觉得我的问题非常接近这些问题:
尽管在他们的情况下,他们正在一个新的过程中调用该孩子,而我正在调用一个源函数,我认为这对fg / bg不会产生相同的影响,对吗?
举个最小的例子,假设我有一个名为main.sh的文件:
trap catchInt SIGINT
reallyQuit=0
function catchInt(){
echo "caught sigint"
if (( $reallyQuit > 0 ));then
echo "really quitting."
exit 1
else
let reallyQuit++
echo "reallyquit is now $reallyQuit"
fi
menu
}
function menu(){
read -ep $'Please choose a number and press enter.\n\t' input
case $input in
1)
child
menu
;;
*)
echo "Quitting"
exit 0
;;
esac
}
source child.sh
# I also source other scripts with utility functions and exported vars
menu
如果我在同一目录中有一个名为child.sh的文件:
function child(){
read -p "Please type something"
# I also use utility functions and exported vars
}
这是上面代码的示例运行,其中我在菜单内单击了ctrl + c,然后在子功能内再次尝试:
bash main.sh
Please choose a number and press enter.
caught sigint
reallyquit is now 1
Please choose a number and press enter.
1
Please type something^C^C^C^C^C (I finally pressed enter)
Please choose a number and press enter.
(I tapped ctrl-c a few times here and finally pressed enter)
Quitting
这里是一个示例,其中我首先输入1,然后输入ctrl-c:
bash main.sh
Please choose a number and press enter.
1
Please type something^Ccaught sigint
reallyquit is now 1
Please choose a number and press enter.
(I tapped ctrl-c a few times here and finally pressed enter)
Quitting
每次发送INT信号时如何使陷阱响应?
答案 0 :(得分:1)
我不确定,但是我认为这是因为当第二次调用menu
时,您仍处于“陷阱处理程序”中。由于仍在处理sigint,因此不会处理第二个sigint。如果您要删除该呼叫,并用menu
将while true; do ...; done
换行,它将起作用:
#! /bin/bash
reallyQuit=0
function catchInt(){
echo "caught sigint"
if (( $reallyQuit > 0 ));then
echo "really quitting."
exit 1
else
let reallyQuit++
echo "reallyquit is now $reallyQuit"
fi
}
trap catchInt SIGINT
function menu(){
read -ep $'Please choose a number and press enter.\n\t' input
case $input in
1)
child
menu
;;
*)
echo "Quitting"
exit 0
;;
esac
}
function child(){
read -p "Please type something"
# I also use utility functions and exported vars
}
# I also source other scripts with utility functions and exported vars
while true; do
menu
done
exit 0
编辑:
为什么要在main.sh中包含child.sh?通常,将创建通用功能并将其包含在子脚本中。这样,您可以在child1.sh,...,childN.sh之间共享main.sh中的功能。如果将source main.sh
添加到child.sh中,陷阱也将起作用。