在Ctrl + C

时间:2018-11-01 16:14:21

标签: bash input signals

TLDR

read函数在被 Ctrl + C 终止后不会停止读取输入,而是在另一个函数结束时等待用户输入紧随其后。

说明

因此,我有一个具有多种功能的循环菜单样式脚本,每个功能对应一个菜单。

现在在我的一项职能中,我有以下几行内容:

printf "Enter your choice: "
read var_boxChoice

在弹出"Enter your choice: "对话框并且读取功能开始等待用户输入之后,我使用 Ctrl + C 键取消该功能。 (这被主菜单功能上方的trap 'f_menu' SIGINT命令所困,因此它不会杀死整个脚本),然后我被转移到主菜单(按预期进行)。

之后,我选择另一个函数,其中仅包含以下代码:

    clear
    printf "Feature is not yet implemented! \nReturning to the main menu in 5 seconds."
    sleep 5

然后出现问题。完成sleep 5之后,无需再返回主菜单,而是从第一个功能开始的read功能等待用户输入。我知道是这样,因为输入错误处理机制告诉我read来自第一个函数。

我该怎么办? 如何取消输入?

恐怕我无法发布更多代码,因此我向您道歉。

谢谢!

编辑:

对于想要完整代码的人来说,这是我为此目的而重新制作的迷你示例。

#!/bin/bash

var_answer1 = 0
var_answer2 = 0

f_blah1(){
    printf "Whatever 1"
    sleep 2
}

f_blah2(){
    printf "Whatever 2"
    sleep 2
}

f_option1(){
    clear
    printf "====================================================================\n"
    printf "What do you want to do?\n"
    printf "====================================================================\n"
    printf "1) Do this\n"
    printf "2) Do that\n"
    printf "====================================================================\n"
    printf "Enter your choice: "
    read var_answer2
    printf "====================================================================\n\n"
    sleep 1

    if [ "$var_answer2" -eq "1" ]; then
        f_blah1
    elif [ "$var_answer2" -eq "2" ]; then
        f_blah2
    else
        clear
        printf "====================================================================\n"
        printf "'$var_boxChoice' is not a viable answer!\nYou can only enter numbers 1 and 2!\n";
        printf "====================================================================\n"
        sleep 3
    fi
}

f_option2(){
    clear
    printf "Meh. I'm sleeping for 5 seconds. Then I'll return to main."
    sleep 5
}

trap 'f_menu' SIGINT

f_menu(){
    clear
    printf "====================================================================\n"
    printf "Select an option:\n"
    printf "====================================================================\n"
    printf "1) Option 1\n"
    printf "2) Option 2\n"
    printf "3) Quit\n"
    printf "====================================================================\n"
    printf "Enter your choice: "
    read var_answer1
    printf "====================================================================\n\n"
    sleep 0.5

    if [ "$var_answer1" -eq "1" ]; then
        f_option1
    elif [ "$var_answer1" -eq "2" ]; then
        f_option2
    elif [ "$var_answer1" -eq "3" ]; then
        printf "====================================================================\n"
        printf "Quitting the app... Thanks for using it!\n"
        printf "====================================================================\n"
        sleep 3
        clear
        exit
    else
        clear
        printf "====================================================================\n"
        printf "'$var_answer' is not a viable answer!\nYou can only enter numbers 1-3!\n";
        printf "====================================================================\n"
        sleep 2
    fi
}

while [ 1 > 0 ]
do 
    f_menu
done

1 个答案:

答案 0 :(得分:0)

您的陷阱只是简单地递归调用f_menu。当它返回时,您将返回到发生信号时的位置,即read命令中。

我尝试放

trap 'continue' SIGINT

while循环中,但是效果不佳。键入 Control-c 后,我必须按 Return 才能使其正常工作。

我发现的解决方法是放

trap 'return' SIGINT

在显示菜单的每个功能中。

#!/bin/bash

var_answer1 = 0
var_answer2 = 0

f_blah1(){
    printf "Whatever 1"
}

f_blah2(){
    printf "Whatever 2"
}

f_option1(){
    trap 'return' SIGINT
    printf "====================================================================\n"
    printf "What do you want to do?\n"
    printf "====================================================================\n"
    printf "1) Do this\n"
    printf "2) Do that\n"
    printf "====================================================================\n"
    printf "Enter your choice: "
    read var_answer2
    printf "====================================================================\n\n"

    if [ "$var_answer2" -eq "1" ]; then
        f_blah1
    elif [ "$var_answer2" -eq "2" ]; then
        f_blah2
    else
        printf "====================================================================\n"
        printf "'$var_boxChoice' is not a viable answer!\nYou can only enter numbers 1 and 2!\n";
        printf "====================================================================\n"
    fi
}

f_option2(){
    printf "Meh. I'm sleeping for 5 seconds. Then I'll return to main.\n"
}

f_menu(){
    trap 'return' SIGINT
    printf "====================================================================\n"
    printf "Select an option:\n"
    printf "====================================================================\n"
    printf "1) Option 1\n"
    printf "2) Option 2\n"
    printf "3) Quit\n"
    printf "====================================================================\n"
    printf "Enter your choice: "
    read var_answer1
    printf "====================================================================\n\n"

    if [ "$var_answer1" -eq "1" ]; then
        f_option1
    elif [ "$var_answer1" -eq "2" ]; then
        f_option2
    elif [ "$var_answer1" -eq "3" ]; then
        printf "====================================================================\n"
        printf "Quitting the app... Thanks for using it!\n"
        printf "====================================================================\n"
        exit
    else
        printf "====================================================================\n"
        printf "'$var_answer' is not a viable answer!\nYou can only enter numbers 1-3!\n";
        printf "====================================================================\n"
    fi
}

while :
do 
    f_menu
done