Skip to content

Instantly share code, notes, and snippets.

@kawarimidoll
Last active March 10, 2024 15:00
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save kawarimidoll/371ee1741897608b945c8338b7a75ac3 to your computer and use it in GitHub Desktop.
Save kawarimidoll/371ee1741897608b945c8338b7a75ac3 to your computer and use it in GitHub Desktop.
Process arguments and options in shell script
#!/bin/bash
usage() {
cat << EOS >&2
sample.sh
USAGE:
bash arg_opt_sample.sh [options] <arg1> [arg2]
ARGS:
arg1 Required argument.
arg2 Optional argument. The default argument is 'arg'.
OPTIONS:
-a, --option-a Option that has no argument.
-b, --option-b <arg> Option that has required argument.
-c, --option-c [arg] Option that has optional argument.
The default argument is 'ccc'.
-h, --help Show this help message.
EOS
}
invalid() {
usage 1>&2
echo "$@" 1>&2
exit 1
}
ARGS=()
while (( $# > 0 ))
do
case $1 in
-h | --help)
usage
exit 0
;;
-a | --option-a)
if [[ -n "$OPT_A" ]]; then
invalid "Duplicated 'option-a'."
exit 1
fi
OPT_A=1
;;
-b | --option-b | --option-b=*)
if [[ -n "$OPT_B" ]]; then
invalid "Duplicated 'option-b'."
exit 1
elif [[ "$1" =~ ^--option-b= ]]; then
OPT_B=$(echo $1 | sed -e 's/^--option-b=//')
elif [[ -z "$2" ]] || [[ "$2" =~ ^-+ ]]; then
invalid "'option-b' requires an argument."
exit 1
else
OPT_B="$2"
shift
fi
;;
-c | --option-c | --option-c=*)
if [[ -n "$OPT_C" ]]; then
invalid "Duplicated 'option-c'."
exit 1
elif [[ "$1" =~ ^--option-c= ]]; then
OPT_C=$(echo $1 | sed -e 's/^--option-c=//')
elif [[ -z "$2" ]] || [[ "$2" =~ ^-+ ]]; then
OPT_C=ccc
else
OPT_C="$2"
shift
fi
;;
-*)
invalid "Illegal option -- '$(echo $1 | sed 's/^-*//')'."
exit 1
;;
*)
ARGS=("${ARGS[@]}" "$1")
;;
esac
shift
done
if [[ "${#ARGS[@]}" -lt 1 ]]; then
invalid "Too few arguments."
exit 1
elif [[ "${#ARGS[@]}" -gt 2 ]]; then
invalid "Too many arguments."
exit 1
fi
get_nth () {
local n=$1
shift
eval echo \$${n}
}
ARG1=$(get_nth 1 "${ARGS[@]}")
ARG2=$(get_nth 2 "${ARGS[@]}")
if [[ -z "$ARG2" ]]; then
ARG2=arg
fi
echo "ARG1 $ARG1"
echo "ARG2 $ARG2"
echo "OPT_A $OPT_A"
echo "OPT_B $OPT_B"
echo "OPT_C $OPT_C"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment