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
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.
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With