Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Command line arguments validation with GetOpts and mandatory parameters

I'm creating a basic script that should take 3 mandatory command line options and each one must be followed by a value. Like this:

$ myscript.sh -u <username> -p <password> -f <hosts.txt>

I'm trying to make sure the user is passing those exact 3 options and their values and nothing else, otherwise I want to print the usage message and exit.

I've been reading on getopts and came up with this:

usage () { echo "Usage : $0 -u <username> -p <password> -f <hostsFile>"; }

if [ $# -ne 6 ]
then
        usage
        exit 1
fi

while getopts u:p:f: opt ; do
   case $opt in
      u) USER_NAME=$OPTARG ;;
      p) USER_PASSWORD=$OPTARG ;;
      f) HOSTS_FILE=$OPTARG ;;
      *) usage; exit 1;;
   esac
done

echo "USERNAME: $USER_NAME"
echo "PASS: $USER_PASSWORD"
echo "FILE: $HOSTS_FILE"

I was hoping that if I do not pass any of my 3 "mandatory" options (i.e: -u -p -f) Optargs validation would catch that via the "*)" case. While that is true for other options such "-a","-b", etc.. does not seem to be the case in this particular case:

$ myscript.sh 1 2 3 4 5 6

Getops does not treat that as invalid input and the script moves on executing the echo commands showing 3 empty variables.

How can I capture the input above as being invalid as it is not in the form of:

$ myscript.sh -u <username> -p <password> -f <hosts.txt>

Thanks!

like image 240
donhector Avatar asked Apr 22 '15 22:04

donhector


People also ask

Should I use getopt or getopts?

The main differences between getopts and getopt are as follows: getopt does not handle empty flag arguments well; getopts does. getopts is included in the Bourne shell and Bash; getopt needs to be installed separately. getopt allows for the parsing of long options ( --help instead of -h ); getopts does not.

What is the purpose of getopts command?

The getopts command is a Korn/POSIX Shell built-in command that retrieves options and option-arguments from a list of parameters. An option begins with a + (plus sign) or a - (minus sign) followed by a character. An option that does not begin with either a + or a - ends the OptionString.

What does getopts mean in Bash?

On Unix-like operating systems, getopts is a builtin command of the Bash shell. It parses command options and arguments, such as those passed to a shell script.

Which one of the following provides the getopts built-in command that can be used by shell scripts to parse the command line options?

sh. getopts is a built-in Bourne shell command used to parse positional parameters and to check for valid options. See sh(1). It supports all applicable rules of the command syntax standard (see Rules 3-10, Intro(1)).


1 Answers

getopts has no concept of "mandatory" options. The colons in u:p:f: mean that, if one of those options happens to be supplied, then an argument to that option is mandatory. The option-argument pairs, however, are always optional.

You can require that the user provide all three though with code such as:

if [ ! "$USER_NAME" ] || [ ! "$USER_PASSWORD" ] || [ ! "$HOSTS_FILE" ]
then
    usage
    exit 1
fi

Place this code after the while getopts loop.

The Role of *)

I was hoping that if I do not pass any of my 3 "mandatory" options (i.e: -u -p -f) Optargs validation would catch that via the "*)" case.

The *) case is executed only if an option other than -u, -p, or -f is supplied. Thus, if someone supplied, for example a -z argument, then that case would run.

like image 174
John1024 Avatar answered Oct 07 '22 06:10

John1024