NAME
Getopt::Long::Bash - Bash option parsing that does what you mean
SYNOPSIS
declare -A OPTS=(
[verbose|v]=
[count |c:=i]=1
)
. getoptlong.sh OPTS "$@"
DESCRIPTION
Why Another Option Parser?
If you've written Bash scripts, you know the pain. You start with a simple script, add a few options with getopts, and then...
"Can we add a --verbose flag?"
Sorry, getopts doesn't do long options.
"The script fails when I put the filename before the options."
Right, getopts requires options to come first.
"I need to pass multiple include paths."
You'll have to handle that yourself.
"Can it validate that --count is a number?"
Write your own validation.
"Users keep asking how to use it."
Write a help message. And keep it in sync with your code. Manually.
Sound familiar?
There Has to Be a Better Way
Perl developers have enjoyed Getopt::Long for decades - a battle-tested option parser that just works. What if Bash had something similar?
That's exactly what getoptlong.sh provides.
Define Once, Get Everything
Instead of scattered getopts calls and manual validation, define your options in one place:
declare -A OPTS=(
[verbose |v ]= # flag (increments with -vvv)
[output |o: ]= # required argument
[config |c? ]= # optional argument
[include |I@ ]= # array (multiple values)
[define |D% ]= # hash (key=value pairs)
[count |n:=i ]=1 # integer validation
[mode |m:=(fast|slow)]=fast # regex validation
)
. getoptlong.sh OPTS "$@"
That's it. One line to parse. You get:
- Long and short options
-
--verboseand-vwork the same way. - Option bundling
-
-vvvincrements verbose three times. - GNU-style flexibility
-
script.sh file.txt --verboseworks. Options and arguments mix freely. - Rich data types
-
Arrays collect multiple
--includepaths. Hashes store--define KEY=VALUEpairs. - Built-in validation
-
=iensures integers,=ffor floats,=(regex)for patterns. Bad input? Clear error message. No corrupted state. - Automatic help
-
--helpgenerates usage from your definitions. Always accurate, zero maintenance. - Callbacks
-
Execute functions when options are parsed. Perfect for
--traceenablingset -x.
Real-World Example
Here's a complete script:
#!/usr/bin/env bash
set -eu
declare -A OPTS=(
[&USAGE]="$0 [options] command..."
[count |c:=i # repeat count ]=1
[sleep |i@=f # interval time ]=
[trace |x! # trace mode ]=
[debug |d # debug level ]=0
)
trace() { [[ $2 ]] && set -x || set +x; }
. getoptlong.sh OPTS "$@"
for (( i = 0; i < count; i++ )); do
"$@"
[[ ${sleep[0]:-} ]] && sleep "${sleep[0]}"
done
Run it:
$ repeat.sh --count=3 --sleep=0.5 echo hello
hello
hello
hello
$ repeat.sh --help
Usage: repeat.sh [options] command...
Options:
--count, -c repeat count (default: 1)
--sleep, -i interval time
--trace, -x trace mode
--debug, -d debug level (default: 0)
Designed for Wrapper Scripts
Building a wrapper around another command? Pass-through mode forwards options untouched:
[jobs|j:>make_opts]= # Collect into array
After --jobs=4, the make_opts array contains ("--jobs" "4"), ready to pass to the underlying command.
Subcommand Support
Call getoptlong multiple times for git-style subcommands:
# Parse global options
getoptlong init GlobalOPTS
getoptlong parse "$@" && eval "$(getoptlong set)"
# Parse subcommand options
case "$1" in
commit) getoptlong init CommitOPTS; ... ;;
esac
INSTALLATION
Via CPAN (Recommended)
cpanm Getopt::Long::Bash
After installation, getoptlong.sh is in your PATH.
Direct Download
curl -o getoptlong.sh \
https://raw.githubusercontent.com/tecolicom/getoptlong/dist/getoptlong.sh
Source Directly (For Quick Tests)
source <(curl -fsSL \
https://raw.githubusercontent.com/tecolicom/getoptlong/dist/getoptlong.sh)
REQUIREMENTS
Bash 4.2 or later (for associative arrays and declare -n).
SEE ALSO
- getoptlong - Complete reference manual
- Getopt::Long::Bash::Tutorial - Step-by-step getting started guide
- https://github.com/tecolicom/getoptlong - Source repository
- https://qiita.com/kaz-utashiro/items/75a7df9e1a1e92797376 - Introduction article (Japanese)
AUTHOR
Kazumasa Utashiro
LICENSE
MIT License