Bash脚本中使用dialog时case语句无法正常工作

7
我最近在尝试使用对话框和bash脚本进行实验。我创建了一个对话框菜单,其中包括三个选项:用户、密码和组,还有一个退出选项。我试图在case语句中为每个选项运行函数,但无论我选择哪个选项,它似乎总是落入到通用的最后一个语句,并输出“Something Else…”语句,而不是运行相关函数中的echo语句,例如echo "Entering Users sub-menu"。
我已经尝试打开调试模式来运行此脚本:
bash -x myscript

我得到了以下输出:
+ choice='Users
Error: Expected a box option.
Use --help to list options.'
+ '[' 'Users
Error: Expected a box option.
Use --help to list options.' '!=' ' Quit ']'
+ case $choice in
+ echo 'Something else.  Where Am I?'
Something else. Where Am I?
+ exit 0

我还在努力弄清楚“Expected a box option”的含义,这似乎与对话框有关,但我也在想我的 Bash 的 if 语句或 case 语句是否有问题。

我的脚本代码:

#!/bin/bash

function quit {
    exit 0
}

function menu {

choice=$(dialog --backtitle "Rob Graves's Bash Scripting" \
--title "Main Menu"  --menu "Choose one" 30 50 4 "Users" \
"- Do something with users" "Passwords"\
 "- Do stuff with passwords"  "Groups" "- Do things with groups" \
 "Quit" "- Exit to desktop" --clear --nocancel 3>&1 1>&2 2>&3)

    if [ "$choice" != "Quit" ]; then

        case $choice in 
            Users)
                users                   #calls users function
                ;;
            Passwords)
                passwords               #calls passwords function
                ;;
            Groups)
                groups                  #calls groups function
                ;;
            *)
                echo "Something else.  Where Am I?"
                ;;
        esac

    else
        echo "Quitting..."
        quit
    fi

}

function users {
    echo "Entering Users sub-menu"
}

function passwords {
    echo "Entering Passwords sub-menu "
}

function groups {
    echo "Entering Groups sub-menu"

menu

exit 0

1
注意--提供对话框GUI的快速替代品是xdialog(命令为“Xdialog”)。这是您脚本的另一个选择。 - David C. Rankin
1个回答

9

你目前的问题似乎是 dialog 命令不喜欢在末尾使用你提到的选项 --clear--nocancel。重新排序后,它应该按预期正常工作。

choice=$(dialog --backtitle "Rob Graves's Bash Scripting" \
                --title     "Main Menu" \
                --clear \
                --nocancel \
                --menu  "Choose one" 30 50 4 \
                "Users"     "- Do something with users" \
                "Passwords" "- Do stuff with passwords" \
                "Groups"    "- Do things with groups" \
                "Quit"      "- Exit to desktop" 3>&1 1>&2 2>&3)

同时,将您的case选项字符串始终引用如下,这是一个好主意。

case "$choice" in
    "Users")
        users                   #calls users function
        ;;
    "Passwords")
        passwords               #calls passwords function
        ;;
    "Groups")
        groups                  #calls groups function
        ;;
    *)
        echo "Something else.  Where Am I?"
esac

请记住,在dialog菜单和case菜单中,您也可以添加"Users"选项,格式为"1 - Users",如下图所示。

enter image description here

以及在case语句中,格式如下:
case "$choice" in
    "1 - Users")

另外,请注意命令users(1)groups(1)是作为 GNU bash 的标准命令之一提供的,如果使用相同的名称作为函数名称,则可能会出现不确定性。请始终选择明确的名称。
请记得在脚本执行失败的情况下以非零退出码退出脚本。例如,在上述默认情况下,请记得添加exit 1,以便在脚本异常退出时增加一种调试方式,以查看未按预期顺序运行的流程。
    *)
        echo "Something else.  Where Am I?"
        exit 1
        ;;

当执行命令时,当您的脚本退出并执行 echo $?将显示返回的代码。此外,在脚本中的函数定义中删除非标准的function关键字。只要脚本在bash shell中运行,就应该没问题。在纯POSIX shell中,可能无法识别该关键字。还应使用#!/usr/bin/env bash以实现可移植性:不同的*nix将bash放置在不同的位置,使用/usr/bin/env是运行在PATH上找到的第一个bash的解决方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接