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

--verbose and -v work the same way.

Option bundling

-vvv increments verbose three times.

GNU-style flexibility

script.sh file.txt --verbose works. Options and arguments mix freely.

Rich data types

Arrays collect multiple --include paths. Hashes store --define KEY=VALUE pairs.

Built-in validation

=i ensures integers, =f for floats, =(regex) for patterns. Bad input? Clear error message. No corrupted state.

Automatic help

--help generates usage from your definitions. Always accurate, zero maintenance.

Callbacks

Execute functions when options are parsed. Perfect for --trace enabling set -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