Bash 脚本难度

Bash 脚本难度

我正在创建一个 bash 脚本,我想创建一个菜单。当我运行代码时,它会显示菜单,但问题是当用户输入选项时,无论选择了什么选项,它都会不断重新打印菜单并反复询问。

#!/bin/bash

declare -i choice=1;

while ((choice!=5))
    do
    echo "Main Menu:"
    echo -e "\t(a) Add"
    echo -e "\t(b) Remove"
    echo -e "\t(c) Seach"
    echo -e "\t(d) Display"
    echo -e "\t(e) Exit"
    echo -n "Please enter your choice:"
    read choice
    case $choice in
           "a"|"A")
            echo "You entered a"
            ;;
            "b"|"B")
            echo "You entered b"
            ;;
            "c"|"C")
            echo "You entered c"
            ;;
            "d"|"D")
            echo "You entered d"
            ;;
            "e"|"E")
            echo "You entered e"
            ((choice=5))
            ;;
            *)
            echo "invalid answer"
            ;;

    esac
done

答案1

无论何时调试某个东西,第一步都是让脚本打印它正在使用的各种变量。例如,在这里,如果你添加一个echo $choice case语句,您将看到,0无论您赋予它什么值,它都会打印。

这是因为您正在使用执行(来自)-i的选项:declarehelp declare

  -i    to make NAMEs have the `integer' attribute

因此,您将该变量声明为一个整数,然后向其传递字母(字符串),并且由于 bash 期望一个整数,因此它将其转换为 0。

下一个问题是,您正在运行一个循环,该循环仅在iswhile时才会退出。即使其余语法都正确,也只会在 choice 时发生这种情况。$choice5e

这是您的脚本的一个工作示例。我已删除了declare不必要的内容。

#!/bin/bash

## Use another variable to exit the loop
ok=0;

while ((ok==0))
    do
    echo "Main Menu:"
    echo -e "\t(a) Add a contact"
    echo -e "\t(b) Remove a contact"
    echo -e "\t(c) Seach contacts"
    echo -e "\t(d) Display contacts"
    echo -e "\t(e) Exit"
    echo -n "Please enter your choice:"
    read choice
    case $choice in
        "a"|"A")
        ok=1
            ;;
        "b"|"B")
        ok=1
            ;;
        "c"|"C")
        ok=1
            ;;
        "d"|"D")
            ok=1
        ;;
        "e"|"E")
            exit
        ;;
            *)
            echo "invalid answer, please try again"
            ;;

    esac
done

echo "You entered $choice"

答案2

您可以使用内置函数来完成此操作select

echo "Main Menu:"
echo -e "\t(a) Add a contact"
echo -e "\t(b) Remove a contact"
echo -e "\t(c) Seach contacts"
echo -e "\t(d) Display contacts"
echo -e "\t(e) Exit"
echo "Please enter your choice:"

choices=("a" "b" "c" "d" "e" "Quit")
select choice in "${choices[@]}"
do
    case $choice in
        "a")
            echo "you chose choice a"
            ;;
        "b")
            echo "you chose choice b"
            ;;
        "c")
            echo "you chose choice c"
            ;;
        "d")
            echo "you chose choice d"
            ;;
        "e")
            echo "you chose choice e"
            ;;
        "Quit")
            break
            ;;
        *) echo invalid option;;
    esac
done

它更易于使用,并且您可以choices从文件中读取您的内容。此外,如果要退出任何菜单,只需在每个菜单后choice添加即可。breakchoice

答案3

打开终端并输入:

sudo apt-get install 9menu  

9menu 从 shell 创建 X 菜单。这是一个简单的程序,允许您从 shell 创建 X 菜单,其中每个菜单项将运行一个命令。

运行以下命令来创建菜单:

9menu -label "Main Menu" 'Add:echo "You entered a"' 'Remove:echo "You entered b"' 'Search:echo "You entered c"' 'Display:echo "You entered d"' 'Exit:echo "You entered e"'

这一切都由这一行命令完成,而且由于 9menu 以图形方式显示菜单,因此无需添加“无效答案”错误条件,因为菜单条目是从主菜单窗口,并且菜单中只有五个可能的条目可以通过鼠标单击来选择。

我建议你对原来的菜单想法做以下改进。当你点击“退出”时,不要显示“你输入了 e”,为什么不使用出口菜单项关闭主菜单窗口并退出 9menu?要这样做,请使用以下命令:

9menu -label "Main Menu" 'Add:echo "You entered a"' 'Remove:echo "You entered b"' 'Search:echo "You entered c"' 'Display:echo "You entered d"' exit  

相关内容