为什么这不循环菜单?

Mon*_*192 7 command-line bash

我在 Ubuntu 机器上使用 GNU bash,版本 4.3.46。由于某种原因,这个 while 循环不能按预期工作。

菜单应该连续循环直到用户决定退出程序,然后有一些错误检查提示用户如果他们确定,然后程序结束。

这是代码:

#!/bin/bash

menu_choice=0
quit_program="n"

while [[ $menu_choice -ne 3 && $quit_program != "y" ]]
do

    printf "1. Backup\n"
    printf "2. Display\n"
    printf "3. Exit\n\n"

    printf "Enter choice: \n"
    read menu_choice

    if [ $menu_choice -eq 3 ]
    then
        printf "Are you sure you want to quit? (y/n)\n"
        read quit_program

    fi

done
Run Code Online (Sandbox Code Playgroud)

我认为这可能与在开始时声明全局变量有关,并且我正在本地读取一个新值...

The*_*rer 7

问题出在您的 while 循环条件中。这一行:

while [[ $menu_choice -ne 3 && $quit_program != "y" ]]
Run Code Online (Sandbox Code Playgroud)

是说“虽然 menu_choice 不是 3并且quit_program 不是 y,请继续循环。” 问题是,如果这些条件中的任何一个不再为真,while 循环将结束。

你想要的是这个:

while [[ $menu_choice -ne 3 || $quit_program != "y" ]]
Run Code Online (Sandbox Code Playgroud)

使用||代替&&. 这样,只要其中一个条件为真,while 循环就会继续循环,而不是两个条件都为真。


Del*_*ean 7

这个更简单的脚本应该适合你

#!/bin/bash

menu_choice=0
quit_program=false

while [ $quit_program == false ]
do

    printf "1. Backup\n"
    printf "2. Display\n"
    printf "3. Exit\n\n"

    printf "Enter choice: \n"
    read menu_choice

    if [ $menu_choice -eq 3 ]
    then
        printf "Are you sure you want to quit? (y/n) "
        read ask
        if [ $ask == "y" ]
        then
            quit_program=true
        fi

    fi

done

printf "\nDone\n"
Run Code Online (Sandbox Code Playgroud)

没有必要继续检查menu_choice,这样就可以从 while 循环检查中删除它。

在我上面的例子中,我只是设置了一个布尔值,quit_program它在循环中被检查。如果用户选择选项 3,然后对确认说“y”,则布尔值设置为 true 以终止循环。

您还可以在不检查布尔值的情况下更进一步:

#!/bin/bash

menu_choice=0

while true
do
    printf "1. Backup\n"
    printf "2. Display\n"
    printf "3. Exit\n\n"

    printf "Enter choice: \n"
    read menu_choice

    if [ $menu_choice -eq 3 ]
    then
        printf "Are you sure you want to quit? (y/n) "
        read ask
        if [ $ask == "y" ]; then break; fi
    fi
done

printf "\nDone\n"
Run Code Online (Sandbox Code Playgroud)

第二个例子完成了同样的事情,但while循环只是在没有检查之前的布尔值的情况下运行。break而是用命令打破了循环。