Skip to content

curatorium/bash-args

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

bash-args

Argument parsing for bash scripts.

Installation

curl -1fsSLR https://raw.githubusercontent.com/curatorium/bash-args/main/args -o .deps/args

Usage

source ./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 $ARGS

All 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.

FUNCTIONS

args:flag

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.

args:opt

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.

args:arg

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.

args:varg

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.

Pattern Matching

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=100

When a pattern contains a capture group, the captured value is assigned to the variable instead of the full match.

Examples

Basic CLI Tool

#!/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[*]}"

Git-like Subcommands

#!/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

With Validation

#!/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"

Limitations

  • 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.
  • --combined flag ordering. Combined short flags (-vfs) must be parsed after all other args:flag and args:opt calls, but before args:arg calls. Otherwise, combined flags may consume characters intended as option values, or positional arguments starting with - may be misinterpreted.

License

MIT