#!/bin/bash
usage() { echo “Usage: $0 [-s <45|90>] [-p
while getopts “:s:p:” o; do
case “${o}” in
s)
s=${OPTARG}
((s == 45 || s == 90)) || usage
;;
p)
p=${OPTARG}
;;
*)
usage
;;
esac
done
shift $((OPTIND-1))
if [ -z “${s}” ] || [ -z “${p}” ]; then
usage
fi
echo “s = ${s}”
echo “p = ${p}”
Example runs:
$ ./myscript.sh
Usage: ./myscript.sh [-s <45|90>] [-p
$ ./myscript.sh -h
Usage: ./myscript.sh [-s <45|90>] [-p
$ ./myscript.sh -s “” -p “”
Usage: ./myscript.sh [-s <45|90>] [-p
$ ./myscript.sh -s 10 -p foo
Usage: ./myscript.sh [-s <45|90>] [-p
$ ./myscript.sh -s 45 -p foo
s = 45
p = foo
$ ./myscript.sh -s 90 -p bar
s = 90
p = bar
The problem with the original code is that:
h: expects parameter where it shouldn’t, so change it into just h (without colon)
to expect -p any_string, you need to add p: to the argument list
Basically : after the option means it requires the argument.
The basic syntax of getopts is (see: man bash):
getopts OPTSTRING VARNAME [ARGS…]
where:
OPTSTRING is string with list of expected arguments,
h – check for option -h without parameters; gives error on unsupported options;
h: – check for option -h with parameter; gives errors on unsupported options;
abc – check for options -a, -b, -c; gives errors on unsupported options;
:abc – check for options -a, -b, -c; silences errors on unsupported options;
Notes: In other words, colon in front of options allows you handle the errors in your code. Variable will contain ? in the case of unsupported option, : in the case of missing value.
OPTARG – is set to current argument value,
OPTERR – indicates if Bash should display error messages.
So the code can be:
#!/usr/bin/env bash
usage() { echo “$0 usage:” && grep ” .) #” $0; exit 0; }
[ $# -eq 0 ] && usage
while getopts “:hs:p:” arg; do
case $arg in
p) # Specify p value.
echo “p is ${OPTARG}”
;;
s) # Specify strength, either 45 or 90.
strength=${OPTARG}
[ $strength -eq 45 -o $strength -eq 90 ]
&& echo “Strength is $strength.”
|| echo “Strength needs to be either 45 or 90, $strength found instead.”
;;
h | *) # Display help.
usage
exit 0
;;
esac
done
Example usage:
$ ./foo.sh
./foo.sh usage:
p) # Specify p value.
s) # Specify strength, either 45 or 90.
h | *) # Display help.
$ ./foo.sh -s 123 -p any_string
Strength needs to be either 45 or 90, 123 found instead.
p is any_string
$ ./foo.sh -s 90 -p any_string
Strength is 90.
p is any_string
See: Small getopts tutorial at Bash Hackers Wiki