I am trying to parse a -temp
option with Bash getopts. I'm calling my script like this:
./myscript -temp /foo/bar/someFile
Here is the code I'm using to parse the options.
while getopts "temp:shots:o:" option; do
case $option in
temp) TMPDIR="$OPTARG" ;;
shots) NUMSHOTS="$OPTARG" ;;
o) OUTFILE="$OPTARG" ;;
*) usage ;;
esac
done
shift $(($OPTIND - 1))
[ $# -lt 1 ] && usage
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.
I know that getopts would be the preferred way in terms of portability but AFAIK it doesn't support long options. getopt supports long options but the BashGuide recommends strongly against it: Never use getopt(1). getopt cannot handle empty arguments strings, or arguments with embedded whitespace.
The ability to process options entered at the command line can be added to the Bash script using the while command in conjunction with the getops and case commands. The getops command reads any and all options specified at the command line and creates a list of those options.
To tell getopts that an option will be followed by an argument, put a colon ” : ” immediately behind the option letter in the options string. If we follow the “b” and “c” in our options string with colons, getopt will expect arguments for these options.
As other people explained, getopts doesn't parse long options. You can use getopt, but it's not portable (and it is broken on some platform...)
As a workaround, you can implement a shell loop. Here an example that transforms long options to short ones before using the standard getopts command (it's simpler in my opinion):
# Transform long options to short ones
for arg in "$@"; do
shift
case "$arg" in
'--help') set -- "$@" '-h' ;;
'--number') set -- "$@" '-n' ;;
'--rest') set -- "$@" '-r' ;;
'--ws') set -- "$@" '-w' ;;
*) set -- "$@" "$arg" ;;
esac
done
# Default behavior
number=0; rest=false; ws=false
# Parse short options
OPTIND=1
while getopts "hn:rw" opt
do
case "$opt" in
'h') print_usage; exit 0 ;;
'n') number=$OPTARG ;;
'r') rest=true ;;
'w') ws=true ;;
'?') print_usage >&2; exit 1 ;;
esac
done
shift $(expr $OPTIND - 1) # remove options from positional parameters
getopts
can only parse short options.
Most systems also have an external getopt
command, but getopt is not standard, and is generally broken by design as it can't handle all arguments safely (arguments with whitespace and empty arguments), only GNU getopt can handle them safely, but only if you use it in a GNU-specific way.
The easier choice is to use neither, just iterate the script's arguments with a while-loop and do the parsing yourself.
See http://mywiki.wooledge.org/BashFAQ/035 for an example.
getopts
is used by shell procedures to parse positional parameters of 1 character only
(no GNU-style long options (--myoption) or XF86-style long options (-myoption))
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