我创建了一个bash陷阱来捕获 CTRL + C 并调用函数ctrl_c。此函数只显示一条消息并启动计数器然后返回主函数。
第一次运行时陷阱工作正常但如果第二次尝试它会显示C ^虽然它确实禁用CTRL + C但它不会再次调用该函数。
有没有办法将陷阱重置为像第一个实例一样运行。
提前致谢。
代码;
function ctrl_c() {
clear
echo "** Trapped CTRL-C"
echo -n "Press [ Enter ] to continue."
read
for i in $(seq 1 5);
do
let timer="5 - $i + 1"
clear
echo "Returning to main menu in.. $timer"
sleep 1
done
main
}
trap ctrl_c INT
答案 0 :(得分:1)
中断处理程序运行时始终阻止信号。在此代码中,您的处理程序永远不会返回,因此信号仍然被阻止。
不返回的信号处理程序通常是个坏主意。如果您只想在信号之后重新启动函数,那么您可以在循环中的子shell中运行它并让处理程序退出,这将仅从子shell退出。
编辑:更新了Adrian的建议。
#!/bin/bash
function ctrl_c() {
clear
echo "Trapped CTRL-C"
echo
for ((timer=5; timer>0; timer--)); do
printf "\rRetunring to main menu in $timer seconds"
sleep 1
done
exit 10
}
function main() {
trap ctrl_c INT
# Doing main stuff
echo "Exiting normally"
exit 0;
}
while ( main ); (($? == 10)); do :; done
答案 1 :(得分:1)
将程序的控制权传递给信号处理程序并不是一个好主意。信号处理程序应尽可能快地完成并返回。因此,您可以在处理程序中启用标志变量,如下所示:
function ctrl_c() {
flag=1
}
function trap_menu() {
clear
for i in $(seq 1 5);
do
let timer="5 - $i + 1"
clear
echo "Returning to main menu in.. $timer"
sleep 1
done
flag=0
}
trap "ctrl_c" INT
flag=0
while ! [ $age ]; do
echo -n "Enter your age> "
while [ $flag -eq 0 ] && ! [ $age ]; do
# Wait for one second
read -t 1 age
done
if [ $flag -eq 1 ]; then trap_menu; fi
done
答案 2 :(得分:0)
你没有回归'到主函数,而是重新调用它,所以你仍然在技术上在你的陷阱处理程序。如果您排除' main'在处理程序结束时调用,bash将在执行流程中断之后返回NEXT命令,您可以继续捕获进一步的中断。见Catch SIGINT in bash, handle AND ignore
function main() {
echo sleeping...
sleep 60
main
}
function ctrl_c() {
echo "** Trapped CTRL-C"
}
trap ctrl_c INT
main
在你的情况下,如果它只是一个读取操作(从用户那里获得菜单选择)失败,那么只需检查输入是否为空并循环回来以获得更多输入。