This script provides a robust and flexible way to parse command-line arguments in Bash or Zsh. It supports various features such as required options, array options, and next argument assignable options. The script is designed following best practices for modularity and maintainability.
ZSH or BASH shells
zsh@^5
bash@^4.20
The argsparser
function parses command-line arguments based on predefined options and variables.
It handles required options, array options, and options that take their values from the next argument.
-
Utility Functions:
array_includes_value
: Checks if an array includes a specific value.escape_double_quote
: Escapes double quotes in a string.check_var_name
: Validates a variable name.split_arg_value
: Splits a string by=
and retrieves the specified field.show_formatted_required_parameters
: Shows formatted required parameters.
-
Main Function:
argsparser
: Parses the command-line arguments.
Arguments are defined with specific formats:
option:=variable_name
for required options.option+=variable_name
for array options.option~=variable_name
for options whose value is the next argument (next argument assign doesn't work with array options).option+:=variable_name
for array and required options.
Never provide the first dash to single dash argument, option
on definition would -option
on usage.
To arguments containing double dash, only provide one, -option
on definition would --option
on usage.
NOTE: options shouldn't contain :
, +
or ~
characters on its name.
This script offers you the option to show the usage description in case of the user add --help
or -h
argument to your script, e.g.: main --help
. Also, in case of not finding an required argument on arguments
provided, it'll print your usage description or, in case not provided, it'll print all required options.
Args parser won't stop the propagation in case of the user only call with the -h
flag, to stop it with success
(returning 0), check the variable helper_was_called
, e.g.:
main() {
local option helper_was_called
usage="Main Function
-o=<option> Some Parameter to be filled"
. ./argsparser.bash
argsparser o=option -- "$usage"
$helper_was_called && return 0
}
#!/bin/bash
# Alias to load argparser
# Define on your .bashrc, .bash_profile or .zshrc
alias load_argparser='. ./argsparser.bash'
main() {
local require_opt next_assign_opt
local -a array_opt args
usage="main function
-r | --required Required argument
--next-assign <next-value> Next assigne value, e.g: --next-assign some-next-value
--arr-var Array value"
load_argparser
argsparser {r,-required}:=require_var -next-assign~=next_assign_opt -arr-var+=array_opt -- "$usage"
# Access the parsed variables
echo "Required Option: $require_opt"
echo "Next Assigne Option: $next_assign_opt"
echo "Array Option: ${array_opt[@]}"
echo "Plain Arguments: ${args[@]}"
}
main "$@"
-
Defining Alias, Options and Variables:
We're defining a alias to easier load when we want to use it, but your alias should be localed in one of you main files (
.bashrc
,.bash_profile
or.zshrc
), don't forget to create the file and point it correctly on the script (./argsparser.bash
).alias load_argparser='. ./argsparser.bash'
Define the variables that will be used to fill with the options parsed. For example:
local require_opt next_assign_opt local -a array_opt args
Notice that we'll work with plain arguments inside the var
args
, you can re-set the arguments positions withset -- $args
right after parsing the args, e.g.:main() { local option local -a args load_argparser argsparser o=option set -- $args # re-set positional args with array values echo "Option: $option" echo "First Plain Argument: $1" } main -o some-arg # output: # Option: -o # First Plain Argument: some-arg
-
Defining usage helper
Defines the usage variable containing the helper to use the function.
usage="main function
-r | --required Required argument
--next-assign <next-value> Next assign value, e.g: --next-assign some-next-value
--arr-var Array value"
-
Loading and calling
argsparser
:Load and call the
argsparser
function with the rules and command-line arguments:. ./argsparser.bash argsparser {r,-required}:=require_var -next-assign~=next_assign_opt -arr-var+=array_opt -- "$usage" -- "$@"
Take a look on the Load Args Parser to more details about why not load globally.
Here we are defining the follow rule:
{r,-required}:=require_var
: Required parameter that will fill the varrequired_var
. The options availables for that will be--required
and-r
.-next-assign~=next_assign_opt
: Next argument option assignment, this will fill the varnext_assign_opt
. The option available for that will be--next-assign
. This should be used likemain --next-assign some-next-assign-value
. Doesn't matter how many arguments come after, the next arg without a option will be assigned to the next argument assign option.-arr-var+=array_opt
: Array parameter that will fill the vararray_opt
. The option available for that will be-arr-var
, which can be used more than once e.g.:main -arr-var=first-value -arr-var=first-value
, which will populate the array assigned to the option.
Also we are passing the usage helper for the script
-- "$usage"
, which is optional, you can just not provide that if not needed by passing forward the parameters, e.g.:main -opt=var -- "$@"
-
Accessing Parsed Variables:
After calling
argsparser
with the options rules, you can access the parsed variables directly:echo "Required Option: $require_opt" echo "Next Assigne Option: $next_assign_opt" echo "Array Option: ${array_opt[@]}" echo "Plain Arguments: ${args[@]}"
To run the example script with command-line arguments:
./example_script.sh -r=some-required-value --next-assign --arr-var="some-arr#1" some-next-assign --arr-var="some-arr#2" argument
In this example:
-r=some-required-value
: Setsrequire_opt
variable tosome-required-value
.--next-assign
: Setsnext_assign_opt
tosome-next-assign
, which comes ahead in the arguments.--arr-var="some-arr#1"
and--arr-var="some-arr#2"
: Addssome-arr#1
andsome-arr#2
to the arrayarray_opt
.argument
: Will be added to the array variableargs
if declared
We recommend watching the return of argsparser since the set -e command closes the current instance of zsh, thus the usage code in zsh would be as follow example:
main {
local option
load_argsparser
argsparser option=option || return $1
}
You should always source the argsparser
file in the place you wanna use it, don't load it in the main
file (.bashrc
, .bash_profile
or `.zsh).
When the file is loaded we get the arguments used in the function without having to pass forward to the function everytime. In case of loading the file globally the arguments stored to be parsed will be the arguments passed to the main file.
The script includes error handling for various cases:
- Invalid variable names.
- Missing required options.
- Conflicts between array and next argument assignable options.
The argsparser
function provides a powerful way to parse command-line arguments in Bash scripts. By following the usage guidelines and example provided, you can easily integrate it into your own scripts to handle complex argument parsing needs.
This README file provides comprehensive documentation for the argsparser
function, including how to define options, call the function, access parsed variables, and handle errors. It also includes a complete example script and command to demonstrate its usage.