Last active
October 3, 2022 08:45
-
-
Save nicola-lunghi/6d70c0e74ba66e7b3ca20612dd502a47 to your computer and use it in GitHub Desktop.
Example of adding a "preamble" to argbash to put code before argbash code.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# m4_ignore( | |
echo "This is just a script template, not the script (yet) - pass it to 'argbash' to fix this." >&2 | |
exit 11 #)[ <-- needed because of Argbash | |
############################################################################### | |
# PREAMBLE | |
############################################################################### | |
# Treat expansion of unset variables as an error and exit immediately | |
# if a command pipeline exits with a non-zero status | |
set -o nounset -o errexit | |
## useful variables | |
script_name="$(basename "${BASH_SOURCE[0]}")" | |
script_version="1.0" | |
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | |
_arg_command="" | |
_arg_config="" | |
_arg_help="" | |
_positionals=() | |
############################################################################### | |
# END PREAMBLE | |
############################################################################### | |
# ] <-- needed because of Argbash | |
# ARG_OPTIONAL_SINGLE([config],[c],[specify a config file],[curdir/.lab_config.conf]) | |
# ARG_POSITIONAL_SINGLE([command],[specify a command to execute],[help]) | |
# ARGBASH_SET_DELIM([ =]) | |
# ARG_OPTION_STACKING([getopt]) | |
# ARG_RESTRICT_VALUES([no-local-options]) | |
# ARG_DEFAULTS_POS([]) | |
# ARG_HELP([Print help function]) | |
# ARG_VERSION([echo "$script_name $script_version"][][]) | |
# ARGBASH_SET_INDENT([ ]) | |
# ARG_POSITIONAL_DOUBLEDASH([]) | |
# ARGBASH_PREPARE() | |
# [ <-- needed because of Argbash | |
############################################################################### | |
# MAIN | |
############################################################################### | |
# argparse stuff | |
parse_commandline "$@" | |
handle_passed_args_count | |
assign_positional_args 1 "${_positionals[@]}" | |
# printf 'Value of --%s: %s\n' 'help' "$_arg_help" | |
printf "Value of '%s': %s\\n" 'command' "${_arg_command}" | |
printf "Value of '%s': %s\\n" 'config' "${_arg_config}" | |
printf "Value of '%s': %s\\n" 'positionals' "${_positionals[*]}" | |
#### MAIN END | |
# ] <-- needed because of Argbash |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
############################################################################### | |
# PREAMBLE | |
############################################################################### | |
# Treat expansion of unset variables as an error and exit immediately | |
# if a command pipeline exits with a non-zero status | |
set -o nounset -o errexit | |
## useful variables | |
script_name="$(basename "${BASH_SOURCE[0]}")" | |
script_version="1.0" | |
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | |
_arg_command="" | |
_arg_config="" | |
_arg_help="" | |
_positionals=() | |
############################################################################### | |
# END PREAMBLE | |
############################################################################### | |
# ARG_OPTIONAL_SINGLE([config],[c],[specify a config file],[curdir/.lab_config.conf]) | |
# ARG_POSITIONAL_SINGLE([command],[specify a command to execute],[help]) | |
# ARGBASH_SET_DELIM([ =]) | |
# ARG_OPTION_STACKING([getopt]) | |
# ARG_RESTRICT_VALUES([no-local-options]) | |
# ARG_DEFAULTS_POS([]) | |
# ARG_HELP([Print help function]) | |
# ARG_VERSION([echo "$script_name $script_version"]) | |
# ARGBASH_SET_INDENT([ ]) | |
# ARG_POSITIONAL_DOUBLEDASH([]) | |
# ARGBASH_PREPARE() | |
# needed because of Argbash --> m4_ignore([ | |
### START OF CODE GENERATED BY Argbash v2.10.0 one line above ### | |
# Argbash is a bash code generator used to get arguments parsing right. | |
# Argbash is FREE SOFTWARE, see https://argbash.io for more info | |
# # When called, the process ends. | |
# Args: | |
# $1: The exit message (print to stderr) | |
# $2: The exit code (default is 1) | |
# if env var _PRINT_HELP is set to 'yes', the usage is print to stderr (prior to $1) | |
# Example: | |
# test -f "$_arg_infile" || _PRINT_HELP=yes die "Can't continue, have to supply file as an argument, got '$_arg_infile'" 4 | |
die() | |
{ | |
local _ret="${2:-1}" | |
test "${_PRINT_HELP:-no}" = yes && print_help >&2 | |
echo "$1" >&2 | |
exit "${_ret}" | |
} | |
# Function that evaluates whether a value passed to an argument | |
# does not violate the global rule imposed by the ARG_RESTRICT_VALUES macro: | |
# The value must not match any long or short option this script uses | |
# Args: | |
# $1: The name of the option | |
# $2: The passed value | |
evaluate_strictness() | |
{ | |
[[ "$2" =~ ^-(-(config|command|help|version)$|[chv]) ]] && die "You have passed '$2' as a value of argument '$1', which makes it look like that you have omitted the actual value, since '$2' is an option accepted by this script. This is considered a fatal error." | |
} | |
# Function that evaluates whether a value passed to it begins by a character | |
# that is a short option of an argument the script knows about. | |
# This is required in order to support getopts-like short options grouping. | |
begins_with_short_option() | |
{ | |
local first_option all_short_options='chv' | |
first_option="${1:0:1}" | |
test "$all_short_options" = "${all_short_options/$first_option/}" && return 1 || return 0 | |
} | |
# THE DEFAULTS INITIALIZATION - POSITIONALS | |
# The positional args array has to be reset before the parsing, because it may already be defined | |
# - for example if this script is sourced by an argbash-powered script. | |
_positionals=() | |
_arg_command="help" | |
# THE DEFAULTS INITIALIZATION - OPTIONALS | |
_arg_config="curdir/.lab_config.conf" | |
# Function that prints general usage of the script. | |
# This is useful if users asks for it, or if there is an argument parsing error (unexpected / spurious arguments) | |
# and it makes sense to remind the user how the script is supposed to be called. | |
print_help() | |
{ | |
printf '%s\n' "Print help function" | |
printf 'Usage: %s [-c|--config <arg>] [-h|--help] [-v|--version] [--] [<command>]\n' "$0" | |
printf '\t%s\n' "<command>: specify a command to execute (default: 'help')" | |
printf '\t%s\n' "-c, --config: specify a config file (default: 'curdir/.lab_config.conf')" | |
printf '\t%s\n' "-h, --help: Prints help" | |
printf '\t%s\n' "-v, --version: Prints version" | |
} | |
# The parsing of the command-line | |
parse_commandline() | |
{ | |
_positionals_count=0 | |
while test $# -gt 0 | |
do | |
_key="$1" | |
# If two dashes (i.e. '--') were passed on the command-line, | |
# assign the rest of arguments as positional arguments and bail out. | |
if test "$_key" = '--' | |
then | |
shift | |
# Handle the case when the double dash is the last argument. | |
test $# -gt 0 || break | |
_positionals+=("$@") | |
_positionals_count=$((_positionals_count + $#)) | |
shift $(($# - 1)) | |
_last_positional="$1" | |
break | |
fi | |
case "$_key" in | |
# We support whitespace as a delimiter between option argument and its value. | |
# Therefore, we expect the --config or -c value. | |
# so we watch for --config and -c. | |
# Since we know that we got the long or short option, | |
# we just reach out for the next argument to get the value. | |
-c|--config) | |
test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1 | |
_arg_config="$2" | |
shift | |
evaluate_strictness "$_key" "$_arg_config" | |
;; | |
# We support the = as a delimiter between option argument and its value. | |
# Therefore, we expect --config=value, so we watch for --config=* | |
# For whatever we get, we strip '--config=' using the ${var##--config=} notation | |
# to get the argument value | |
--config=*) | |
_arg_config="${_key##--config=}" | |
evaluate_strictness "$_key" "$_arg_config" | |
;; | |
# We support getopts-style short arguments grouping, | |
# so as -c accepts value, we allow it to be appended to it, so we watch for -c* | |
# and we strip the leading -c from the argument string using the ${var##-c} notation. | |
-c*) | |
_arg_config="${_key##-c}" | |
evaluate_strictness "$_key" "$_arg_config" | |
;; | |
# The help argurment doesn't accept a value, | |
# we expect the --help or -h, so we watch for them. | |
-h|--help) | |
print_help | |
exit 0 | |
;; | |
# We support getopts-style short arguments clustering, | |
# so as -h doesn't accept value, other short options may be appended to it, so we watch for -h*. | |
# After stripping the leading -h from the argument, we have to make sure | |
# that the first character that follows coresponds to a short option. | |
-h*) | |
print_help | |
exit 0 | |
;; | |
# See the comment of option '--help' to see what's going on here - principle is the same. | |
-v|--version) | |
echo "$script_name $script_version" | |
exit 0 | |
;; | |
# See the comment of option '-h' to see what's going on here - principle is the same. | |
-v*) | |
echo "$script_name $script_version" | |
exit 0 | |
;; | |
*) | |
_last_positional="$1" | |
_positionals+=("$_last_positional") | |
_positionals_count=$((_positionals_count + 1)) | |
;; | |
esac | |
shift | |
done | |
} | |
# Check that we receive expected amount positional arguments. | |
# Return 0 if everything is OK, 1 if we have too little arguments | |
# and 2 if we have too much arguments | |
handle_passed_args_count() | |
{ | |
test "${_positionals_count}" -le 1 || _PRINT_HELP=yes die "FATAL ERROR: There were spurious positional arguments --- we expect between 0 and 1, but got ${_positionals_count} (the last one was: '${_last_positional}')." 1 | |
} | |
# Take arguments that we have received, and save them in variables of given names. | |
# The 'eval' command is needed as the name of target variable is saved into another variable. | |
assign_positional_args() | |
{ | |
local _positional_name _shift_for=$1 | |
# We have an array of variables to which we want to save positional args values. | |
# This array is able to hold array elements as targets. | |
# As variables don't contain spaces, they may be held in space-separated string. | |
_positional_names="_arg_command " | |
shift "$_shift_for" | |
for _positional_name in ${_positional_names} | |
do | |
test $# -gt 0 || break | |
eval "$_positional_name=\${1}" || die "Error during argument parsing, possibly an Argbash bug." 1 | |
shift | |
done | |
} | |
# Call the function that assigns passed optional arguments to variables: | |
# parse_commandline "$@" | |
# Then, call the function that checks that the amount of passed arguments is correct | |
# followed by the function that assigns passed positional arguments to variables: | |
# handle_passed_args_count | |
# assign_positional_args 1 "${_positionals[@]}" | |
# OTHER STUFF GENERATED BY Argbash | |
### END OF CODE GENERATED BY Argbash (sortof) ### ]) | |
# [ <-- needed because of Argbash | |
############################################################################### | |
# MAIN | |
############################################################################### | |
# argparse stuff | |
parse_commandline "$@" | |
handle_passed_args_count | |
assign_positional_args 1 "${_positionals[@]}" | |
# printf 'Value of --%s: %s\n' 'help' "$_arg_help" | |
printf "Value of '%s': %s\\n" 'command' "${_arg_command}" | |
printf "Value of '%s': %s\\n" 'config' "${_arg_config}" | |
printf "Value of '%s': %s\\n" 'positionals' "${_positionals[*]}" | |
#### MAIN END | |
# ] <-- needed because of Argbash |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment