0

I want getopt to send my user to a help page if they don't supply an option. Goal: If the user specifies no command line or -h, set flag_help to 1.

flag_help=0
flag_test_user=0
flag_demo_user=1
flag_skip_initial_pause=0

while getopts 'hdts' flag; do
    case ${flag} in
        h)
            flag_help=1
            ;;
        d)
            echo "Using Demo Mode"
            flag_test_user=0
            flag_demo_user=1
            ;;
        t)
            echo "Using Test Mode"
            flag_test_user=1
            flag_demo_user=0
            ;;
        s)
            echo "Will skip initial pause.."
            flag_skip_initial_pause=1
            ;;
        *)
            flag_help=1
            ;;
    esac
done

echo "flag_help: $flag_help"

I then test it:

$ sh tools/setup-demo.sh
flag_help: 0
$ sh tools/setup-demo.sh  -h
flag_help: 1

I must have some oddball error in there, but I'm not sure what. To be safe, I did some research and there is a great example thread here: An example of how to use getopts in bash

My syntax seems correct based on that.

What am I doing wrong?

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Dustin
  • 1
  • 1

2 Answers2

0

If the user specifies no command line or -h, set the flag_help to 1.

Detect that.

if (($# == 0)); then
    flag_help=1
fi
while getopt ......
    ...
done
KamilCuk
  • 120,984
  • 8
  • 59
  • 111
  • Okay. I see my logic error. The *) is saying "for anything that does not match" not "for no command-line OR anything that does not match". WOW. Totally missed the obvious. Great catch, thank you! – Dustin Feb 02 '22 at 17:26
0

In order to be compatible and not to tie to bash, I recommend you to use the getopt(1) command. This way you will be compatible with any bourne shell and you will not depend on bash(1) internal command.

For reference, read the manual page of getopt(1), to check how to use the getopt(1) command.

flag_help=1
flag_test_user=0
flag_demo_user=1
flag_skip_initial_pause=0

args=`getopt hdts $*`
set -- $args

while :; do
    case "$1" in
        -h)
            flag_help=1
            flag_test_user=0
            flag_demo_user=0
            shift
            ;;
        -d)
            echo "Using Demo Mode"
            flag_help=0
            flag_test_user=0
            flag_demo_user=1
            shift
            ;;
        -t)
            echo "Using Test Mode"
            flag_help=0
            flag_test_user=1
            flag_demo_user=0
            shift
            ;;
        -s)
            echo "Will skip initial pause.."
            flag_skip_initial_pause=1
            flag_help=0
            shift
            ;;
        --)
            shift
            break;
            ;;
    esac
done

echo "flag_help: $flag_help"
echo nonopt args: "$@"

This way you will be compatible with any bourne shell and not only bash(1)

If you want to use it with the bash getopts command, then:

flag_help=1
flag_test_user=0
flag_demo_user=1
flag_skip_initial_pause=0

while getopts 'hdts' flag $*; do
    case ${flag} in
        h)
            flag_help=1
            ;;
        d)
            echo "Using Demo Mode"
            flag_help=0
            flag_test_user=0
            flag_demo_user=1
            ;;
        t)
            echo "Using Test Mode"
            flag_help=0
            flag_test_user=1
            flag_demo_user=0
            ;;
        s)
            echo "Will skip initial pause.."
            flag_help=0
            flag_skip_initial_pause=1
            ;;
        *)
            ;;
    esac
done

echo "flag_help: $flag_help"

Can be a possible solution to your problem. It is better to initially set flag_help to 1, and in case one of the options is selected, to set it at 0.

Luis Colorado
  • 10,974
  • 1
  • 16
  • 31