Skip to content

Instantly share code, notes, and snippets.

@Buntelrus
Created May 21, 2023 00:09
Show Gist options
  • Save Buntelrus/a6fe78e3c792f4ec9dfe22534f25b3e8 to your computer and use it in GitHub Desktop.
Save Buntelrus/a6fe78e3c792f4ec9dfe22534f25b3e8 to your computer and use it in GitHub Desktop.
Parse Arguments in Bash in a convenient way
#!/bin/bash -e
source parse-arguments.sh
REQUIRED_ARGUMENTS=(
"arg-1"
"arg-2"
)
OPTIONAL_ARGUMENTS=(
"opt-1"
"opt-2"
)
ARGUMENT_FLAGS=(
"dry-run"
)
parseArguments --required=REQUIRED_ARGUMENTS --optional=OPTIONAL_ARGUMENTS --flags=ARGUMENT_FLAGS -- "$@"
# accessing defined arguments
echo "arg-1: $arg_1"
echo "arg-2: $arg_2"
echo "opt-1: $opt_1"
echo "opt-2: $opt_2"
echo "dry-run: $dry_run"
# accessing other arguments
echo "arguments: ${arguments[*]}"
# ./example.sh some --arg-1=foo other --arg-2=bar --opt-1=baz --dry-run arguments
###### output: ######
# arg-1: foo
# arg-2: bar
# opt-1: baz
# opt-2:
# dry-run: true
# arguments: some other arguments
#!/bin/bash -e
function convertBashVar() {
echo "${1//-/_}"
}
function parseArguments() {
# read the options
OPTS=`getopt -o "" --longoptions required:,optional:,flags: -- "$@"`
eval set -- "$OPTS"
while true ; do
case "$1" in
--required)
local -n REF_REQUIRED_ARGUMENTS=$2
shift 2
;;
--optional)
local -n REF_OPTIONAL_ARGUMENTS=$2
shift 2
;;
--flags)
local -n REF_ARGUMENT_FLAGS=$2
shift 2
;;
--)
shift
break
;;
*)
echo "Internal error!"
exit 1
;;
esac
done
LONG_OPTIONS=""
if [ -n "${REF_OPTIONAL_ARGUMENTS}" ]; then
LONG_OPTIONS+="$(printf "%s::," "${REF_OPTIONAL_ARGUMENTS[@]}")"
fi
if [ -n "${REF_REQUIRED_ARGUMENTS}" ]; then
LONG_OPTIONS+="$(printf "%s:," "${REF_REQUIRED_ARGUMENTS[@]}")"
fi
if [ -n "${REF_ARGUMENT_FLAGS}" ]; then
LONG_OPTIONS+="$(printf "%s," "${REF_ARGUMENT_FLAGS[@]}")"
fi
if [ -z "$LONG_OPTIONS" ]; then
echo "No arguments provided"
echo "Usage: $0 --required=REQUIRED_ARGUMENTS --optional=OPTIONAL_ARGUMENTS --flags=ARGUMENT_FLAGS -- \$@"
exit 1
fi
# read arguments
opts=$(getopt \
--longoptions "$LONG_OPTIONS" \
--name "$(basename "$0")" \
--options "" \
-- "$@"
)
eval set -- $opts
for (( i = 1; i < $# + 1; )); do
ArgName="${!i}"
ArgName="${ArgName#--}"
ValueIndex=$(($i + 1))
Value="${!ValueIndex}"
if [ -z "$ArgName" ]; then
arguments=("${@:$(( $i + 1 ))}")
break
else
if [[ " ${REF_OPTIONAL_ARGUMENTS[*]} " =~ " ${ArgName} " ]]; then
declare -g "$(convertBashVar "$ArgName")=$Value"
i=$(($i + 2))
elif [[ " ${REF_REQUIRED_ARGUMENTS[*]} " =~ " ${ArgName} " ]]; then
declare -g "$(convertBashVar "$ArgName")=$Value"
i=$(($i + 2))
elif [[ " ${REF_ARGUMENT_FLAGS[*]} " =~ " ${ArgName} " ]]; then
declare -g "$(convertBashVar "$ArgName")=true"
i=$(($i + 1))
else
echo "Error: Argument name '$ArgName' is not valid"
exit 1
fi
fi
done
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment