Argument parsing for bash scripts.
curl -1fsSLR https://raw.githubusercontent.com/curatorium/bash-args/main/args -o .deps/argssource ./args
# Initialize the ARGS array with script arguments
ARGS=("$@")
# Parse flags, options, and positional arguments
args:flag verbose v # variable $verbose will be set to true if flag present
args:opt name n # variable $name will be set to the value provided
args:arg file # variable $file will be set to if present
args:varg files # variable $files will be set to the rest of values from $ARGSAll functions operate on the ARGS array, consuming matched tokens and leaving unmatched ones for subsequent parsing.
Ideally inside functions you will be using local variables to avoid polluting the global scope.
Parse a boolean flag (e.g., -v, --verbose)
args:flag [-r|--required] [-c|--combined] <long> <short> [--err <msg>] | Flag | Description |
|---|---|
[-r|--required] |
Make the flag required. |
[-c|--combined] |
Allow matching within combined short flags (e.g., -vfs). Read combined flags LAST to avoid conflicts with attached option values. |
| Argument | Description |
|---|---|
<long> |
Long name of the flag (also used as variable name). |
<short> |
Short (1 letter) name of the flag. Use "" for long-only. |
| Option | Description |
|---|---|
[--err <msg>] |
Error message printed to stderr on failure. |
| Return | Description |
|---|---|
0 |
Flag found or optional and absent. |
1 |
Flag absent and required. |
Parse an option with a value (e.g., -n foo, --name=foo)
args:opt [-r|--required] <long> <short> [pattern] [--err <msg>] | Flag | Description |
|---|---|
[-r|--required] |
Make the option required. |
| Argument | Description |
|---|---|
<long> |
Long name of the option (also used as variable name). |
<short> |
Short (1 letter) name of the option. Use "" for long-only. |
[pattern] |
RegEx pattern to validate value. Default "(.*)". |
| Option | Description |
|---|---|
[--err <msg>] |
Error message printed to stderr on failure. |
| Return | Description |
|---|---|
0 |
Option found and matches, or absent and optional. |
1 |
Option absent and required, or found and mismatched. |
Parse a positional argument
args:arg [-o|--optional] <name> [pattern] [--err <msg>] | Flag | Description |
|---|---|
[-o|--optional] |
Make the argument optional. |
| Argument | Description |
|---|---|
<name> |
Variable name to assign the captured value. |
[pattern] |
RegEx pattern to validate value. Default "(.*)". |
| Option | Description |
|---|---|
[--err <msg>] |
Error message printed to stderr on failure. |
| Return | Description |
|---|---|
0 |
Argument found and matches, or absent and optional. |
1 |
Argument absent and required, or found and mismatched. |
Parse variadic (remaining) arguments into an array
args:varg [-o|--optional] <name> [--err <msg>] | Flag | Description |
|---|---|
[-o|--optional] |
Make the arguments optional. |
| Argument | Description |
|---|---|
<name> |
Array variable name to capture remaining values. |
| Option | Description |
|---|---|
[--err <msg>] |
Error message printed to stderr on failure. |
| Return | Description |
|---|---|
0 |
At least one argument found, or optional and none found. |
1 |
No arguments and required. |
Options and arguments support RegEx patterns for validation:
# Numeric validation
args:opt port p '^\[0-9\]+$'
# URL validation
args:arg url '^https?://'
# Capture groups extract specific parts
args:opt ord o '^:(\[0-9\]{3})$' # --ord :100 -> ord=100When a pattern contains a capture group, the captured value is assigned to the variable instead of the full match.
#!/bin/bash
source /usr/local/bin/args
ARGS=("$@")
args:flag verbose v
args:flag -r help h --err "Missing required --help flag"
args:opt output o
args:arg input
args:varg -o extra
echo "verbose: $verbose"
echo "output: $output"
echo "input: $input"
echo "extra: ${extra[*]}"#!/bin/bash
source /usr/local/bin/args
ARGS=("$@")
args:flag verbose v
args:arg command '^(clone|pull|push)$' --err "Unknown command"
args:varg -o cmd_args
case "$command" in
clone) git_clone "${cmd_args[@]}" ;;
pull) git_pull "${cmd_args[@]}" ;;
push) git_push "${cmd_args[@]}" ;;
esac#!/bin/bash
source /usr/local/bin/args
ARGS=("$@")
args:opt port p '^\[0-9\]+$' --err "Port must be numeric" || exit 1
args:opt host h '^\[a-z0-9.-\]+$' --err "Invalid hostname" || exit 1
args:arg url '^https?://' --err "URL must start with http(s)://" || exit 1
echo "Connecting to $url via $host:$port"- No
--separator handling. There is no built-in support for--to signal end-of-options. Arguments after--are not treated differently. - No attached quoting. Values with spaces must be passed as separate shell words (e.g.,
--name "foo bar"). Attached forms like--name="foo bar"may not preserve quoting as expected. --combinedflag ordering. Combined short flags (-vfs) must be parsed after all otherargs:flagandargs:optcalls, but beforeargs:argcalls. Otherwise, combined flags may consume characters intended as option values, or positional arguments starting with-may be misinterpreted.
MIT