package Getopt::Long::Bash;
our $VERSION = "0.5.0";
1;
__END__
=encoding utf-8
=head1 NAME
Getopt::Long::Bash - Bash option parsing that does what you mean
=head1 SYNOPSIS
declare -A OPTS=(
[verbose|v]=
[count |c:=i]=1
)
. getoptlong.sh OPTS "$@"
=head1 DESCRIPTION
=head2 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 C<getopts>, and then...
I<"Can we add a --verbose flag?">
Sorry, C<getopts> doesn't do long options.
I<"The script fails when I put the filename before the options.">
Right, C<getopts> requires options to come first.
I<"I need to pass multiple include paths.">
You'll have to handle that yourself.
I<"Can it validate that --count is a number?">
Write your own validation.
I<"Users keep asking how to use it.">
Write a help message. And keep it in sync with your code. Manually.
Sound familiar?
=head2 There Has to Be a Better Way
Perl developers have enjoyed L<Getopt::Long> for decades - a
battle-tested option parser that just works. What if Bash had
something similar?
That's exactly what B<getoptlong.sh> provides.
=head2 Define Once, Get Everything
Instead of scattered C<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:
=over 4
=item B<Long and short options>
C<--verbose> and C<-v> work the same way.
=item B<Option bundling>
C<-vvv> increments verbose three times.
=item B<GNU-style flexibility>
C<script.sh file.txt --verbose> works. Options and arguments mix freely.
=item B<Rich data types>
Arrays collect multiple C<--include> paths. Hashes store C<--define KEY=VALUE> pairs.
=item B<Built-in validation>
C<=i> ensures integers, C<=f> for floats, C<=(regex)> for patterns.
Bad input? Clear error message. No corrupted state.
=item B<Automatic help>
C<--help> generates usage from your definitions. Always accurate,
zero maintenance.
=item B<Callbacks>
Execute functions when options are parsed. Perfect for C<--trace>
enabling C<set -x>.
=back
=head2 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)
=head2 Designed for Wrapper Scripts
Building a wrapper around another command? Pass-through mode forwards
options untouched:
[jobs|j:>make_opts]= # Collect into array
After C<--jobs=4>, the C<make_opts> array contains C<("--jobs" "4")>,
ready to pass to the underlying command.
=head2 Subcommand Support
Call C<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
=head1 INSTALLATION
=head2 Via CPAN (Recommended)
cpanm Getopt::Long::Bash
After installation, C<getoptlong.sh> is in your PATH.
=head2 Direct Download
curl -o getoptlong.sh \
https://raw.githubusercontent.com/tecolicom/getoptlong/dist/getoptlong.sh
=head2 Source Directly (For Quick Tests)
source <(curl -fsSL \
https://raw.githubusercontent.com/tecolicom/getoptlong/dist/getoptlong.sh)
=head1 REQUIREMENTS
Bash 4.2 or later (for associative arrays and C<declare -n>).
=head1 SEE ALSO
=over 4
=item L<getoptlong> - Complete reference manual
=item L<Getopt::Long::Bash::Tutorial> - Step-by-step getting started guide
=item L<https://github.com/tecolicom/getoptlong> - Source repository
=item L<https://qiita.com/kaz-utashiro/items/75a7df9e1a1e92797376> - Introduction article (Japanese)
=back
=head1 AUTHOR
Kazumasa Utashiro
=head1 LICENSE
MIT License
=cut