Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

bash script case statements not working using dialog

Tags:

bash

I've been experimenting with dialog and bash scripting lately. I created a dialog menu with three options: Users, Passwords, and Groups then also a quit option. I'm trying to run functions for each of these in a case statement but it always seems to fall through to the catchall last statement and output the echo "Something Else..." statement regardless of which option I choose instead of say running the echo statements in the related function, e.g. echo "Entering Users sub-menu"

I've tried running this with debugging on:

bash -x myscript

and I get the following output:

+ 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

I'm still trying to figure out what "Expected a box option" means which sounds like its related to dialog but I'm also wondering if there's something broken with my if statement or case statement in bash.

the code to my script:

#!/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
like image 266
robgraves Avatar asked Apr 11 '19 17:04

robgraves


1 Answers

Your immediate options seems to be that dialog command does not like the options --clear and --nocancel options at the end as you have mentioned. Re-ordering it seems to work fine as expected

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)

Also it would be good idea to always quote your case option strings as below

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

Also remember you can also add options for "Users" as "1 - Users" in both the dialog menu and in the case menu as below.

enter image description here

and in case statement as

case "$choice" in
    "1 - Users")

Also note that the commands users(1) and groups(1) are standard commands available as part of GNU bash and using the same name for functions has a possibility of bringing an uncertainty. Always choose names that are unambiguous.

Remember to exit the script with a non-zero exit code on failure cases from the script. For e.g. on the default case above, remember to add an exit 1, so that it adds one other way of debug facility to look in, when the script exits abnormally, not running the expected flow of sequence.

    *)
        echo "Something else.  Where Am I?"
        exit 1
        ;;

When this is hit and when your script exits and doing echo $? would have shown the code returned.

Also drop the non-standard function keyword from the function definition in the script. As long as the script runs in bash shell it should be fine, on a pure POSIX only shell, the keyword might not be recognized.

Also you should use #!/usr/bin/env bash for portability: different *nixes put bash in different places, and using /usr/bin/env is a workaround to run the first bash found on the PATH.

like image 131
Inian Avatar answered Sep 19 '22 22:09

Inian