This repository is intended as a git submodule
for other Bash scripts that'd be fancier if they'd parse arguments.
Bash version 4.4
or greater and the following command line utilities;
-
printf
for returning values between functions -
sed
for scrubbing values within select functions -
declare
with-a
and-g
options available for declaring globally scoped Bash variables and arrays -
local
with-n
option available for passing references to variables between functions
See
info printf
andinfo sed
for documentation andhelp declare
andhelp local
for more information on additional options.
Bash Variables
_module_https_url='https://github.com/bash-utilities/argument-parser.git'
_module_relative_path='modules/argument-parser'
Bash Submodule Commands
cd "<your-git-project-path>"
mkdir -vp "modules"
git submodule add -b master --name argument-parser "${_module_https_url}" "${_module_relative_path}"
Your Quick Start Section
Clone with the following to avoid incomplete downloads
git clone --recurse-submodules <url-for-your-project>
Update/upgrade submodules via
git submodule update --init --recursive
git submodule update --merge
#!/usr/bin/env bash
## Find true directory this script resides in
__SOURCE__="${BASH_SOURCE[0]}"
while [[ -h "${__SOURCE__}" ]]; do
__SOURCE__="$(find "${__SOURCE__}" -type l -ls | sed -n 's@^.* -> \(.*\)@\1@p')"
done
__DIR__="$(cd -P "$(dirname "${__SOURCE__}")" && pwd)"
## Source module code within this script
source "${__DIR__}/modules/argument-parser/argument-parser.sh"
## Save passed arguments and acceptable arguments to Bash arrays
_passed_args=("${@:?No arguments provided}")
_acceptable_args=(
'--help|-h:bool'
'--directory-path|-d:path'
'--file-name:print-nil'
)
## Pass arrays by reference/name to the `argument_parser` function
argument_parser '_passed_args' '_acceptable_args'
_exit_status="$?"
## Print documentation for the script and exit, or allow further execution
if ((_help)) || ((_exit_status)); then
cat <<EOF
Augments script responds to
--help | -h
Prints this message and exits
--directory-path
Example augment for paths such as ${_directory_path:-/tmp}
<file-name>
Example argument that may print ${_file_name:-a file name}
EOF
exit "${_exit_status:-0}"
fi
## Do scripted things with passed arguments, however, remember to check if
## required values are not set and either throw an error or set a default
printf '_directory_path -> %s\n' "${_directory_path:?--directory-path not provided}"
printf '_file_name -> %s\n' "${_file_name:-output.log}"
Arguments such as --file-name
are transmuted into variable names like _file_name
, and short options may be listed with pipes (|
) as a separator; eg. --directory-path|-d|--dpath
would match and set the _directory_path
variable for -d
, or --dpath
, etc. The first option listed will become the variable name, thus it's a good idea to list the long option first, eg. -d|--directory-path
would be a bad idea as that would set a variable named _d
... a nightmare to debug.
Available argument parsing types are
-
:bool
sets0
or1
forfalse
ortrue
if related argument was passed -
:raw
sets unfiltered value for related argument -
:path
sets value for related argument minus non-alphanumeric or;~
,+
,_
,.
,@
,:
,-
, characters as well as removing duplicated..
and/or--
from the beginning of passed value -
:posix
filters passed value for non-alphanumeric or;_
,.
,-
, characters as well as removing duplicated..
and/or--
from the beginning of passed value. Additionally the_
,.
,-
characters are scrubbed from both the beginning and end of passed value, and only the first32
characters that pass these constraints are set -
:print
sets passed value minus any non-[:print:]
-able characters -
:regex
similar to:print
, but also allows for tabs (\t
) at the beginning and new lines (\n
) at the end of the passed value -
:list
scrubs leading duplicated..
and/or--
from passed value and sets anything alphanumeric and;,
,+
,_
,.
,@
,:
,-
characters if any from passed value -
:alpha_numeric
scrubs any non-alphanumeric characters from passed value
Note,
:list
does not set an array but instead a string that contains the most common list separators, in the future an:array
type might be added to set a Bash arrays too.
These are intended for catching or forgiving typos, and should not be considered secure in untrusted and/or hostile environments.
The -nil
modifier may be appended to any but :bool
option types to make an argument greedy, eg. --file-name
from the above example script will also set from something like script-name.sh --directory-path=/tmp file-name.ext
meaning that the --file-name
option was assumed to prefix the file-name.ext
value.
One warning regarding the -nil
modifier, place argument options using -nil
at the end/bottom of the _acceptable_args
Bash array, eg...
_acceptable_args=(
'--help|-h:bool'
'--file-name|-f:print-nil'
'--directory-path|-d:path'
)
... would be lead to a bad time when attempting to use the values within _file_name
and _directory_path
variables.
Multiple -nil
modified options maybe stacked, eg...
_acceptable_args=(
'--help|-h:bool'
'--source-path|-s:path-nil'
'--destination-path|-d:path-nil'
)
git add .gitmodules
git add modules/argument-parser
## Add any changed files too
git commit -F- <<'EOF'
Submodule `bash-utilities/argument-parser` added for argument parsing
## Add anything else of note...
EOF
git push origin gh-pages
If upgrading from v0.0.2
to v0.0.3
then scrubber functions have been renamed! Eg. arg_scrubber_regex
is now argument_parser__scrub__regex
to avoid clobbering functions that maybe sourced within scripts making use of this project. This should not effect those only utilizing the argument_parser
function.
Argument Parser documentation from Bash Utilities
Copyright (C) 2020 S0AndS0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; version 3 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.