0

我创建了一个 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
4

3 回答 3

2

将程序的控制权传递给信号处理程序并不是一个好主意。信号处理程序应该尽快完成并返回。因此,您可以在处理程序中启用标志变量,如下所示:

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
于 2015-02-26T15:04:20.980 回答
1

在中断处理程序运行时,信号总是被阻塞。在此代码中,您的处理程序永远不会返回,因此信号保持阻塞状态。

不返回的信号处理程序通常是个坏主意。如果您只想在一个信号后重新启动一个函数,那么您可以在循环内的子shell中运行它并让处理程序退出,这将只从子shell退出。

编辑:更新了阿德里安的建议。

    #!/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
于 2015-02-26T14:34:09.923 回答
0

您不是“返回”到主函数,而是重新调用它,因此从技术上讲,您仍然在陷阱处理程序中。如果您在处理程序结束时排除“main”调用,bash 将在执行流程中断后返回到 NEXT 命令,您可以继续捕获更多中断。请参阅bash 中的 Catch SIGINT、处理和忽略

function main() {
    echo sleeping...
    sleep 60
    main
}

function ctrl_c() {
    echo "** Trapped CTRL-C"
}

trap ctrl_c INT

main

在您的情况下,如果它只是一个失败的读取操作(从用户那里获取菜单选择),那么只需检查输入是否为空并循环返回以获取更多输入。

于 2015-02-26T14:37:11.560 回答