Here you go, a working version of your code. I'll break out every-so-often to try and explain why I've changed what I've changed
#!/bin/bash
#
# Adapted from https://www.shellscript.sh/examples/getopt/
#
I prefer to initialise variables to an empty value, and then substitute text inside error messages if necessary. Your user_type=unset could work, setting the variable to the text unset but it prevents simple tests later on such as if [ -z "$user_type ]; then echo "the variable user_type has no value"; fi, and definitely breaks if the user supplies unset as a literal value:
user_type=
user_id=
country=
dev_env=
position_id=
usage(){
>&2 cat << EOF
Usage: $0]
[ -a | --user_type input
[ -b | --user_id input ]
[ -c | --country input ]
[ -d | --dev_env input ]
[ -e | --position_id input ]
EOF
exit 1
}
No point using $@ because (a) you didn't double-quote it, and (b) you're writing a string rather than a series of values. (Look up the difference between $*, $@, and "$@" if you don't follow this):
>&2 echo "[$*] passed to script"
if ! args=$(getopt -a -o ha:b:c:d: --long help,user_type:,user_id:,country:,dev_env:,position_id: -- "$@")
then
usage
fi
>&2 echo "getopt creates [$args]"
Don't forget the double quotes around $args:
eval set -- "$args"
while :
do
case $1 in
-a | --user_type) user_type=$2 ; shift 2 ;;
-b | --user_id) user_id=$2 ; shift 2 ;;
-h | --help) usage ; shift ;;
-c | --country) country=$2 ; shift 2 ;;
-d | --dev_env) dev_env=$2 ; shift 2 ;;
-e | --position_id) position_id=$2 ; shift 2 ;;
# -- means the end of the arguments; drop this, and break out of the while loop
--) shift; break ;;
*) >&2 echo "Unsupported option: $1"
usage ;;
esac
done
The shift statements (above) eat the arguments as they're processed. But in a moment you want to print the remaining arguments, so there's no point bailing with a usage error if there are none left. Code removed.
In this next section, variables such as $user_type may be unset, so they'll have no value. Here the ${user_type:-<unset>} displays <unset> if the value is unset/empty:
>&2 echo "user_type : ${user_type:-<unset>}"
>&2 echo "user_id : ${user_id:-<unset>} "
>&2 echo "country : ${country:-<unset>}"
>&2 echo "dev_env : ${dev_env:-<unset>}"
>&2 echo "position_id : ${position_id:-<unset>}"
>&2 echo "$# parameter/s remaining: $*"
>&2 echo "Looping through remaining parameter/s:"
Double-quote the "$@" so that words are treated as single elements even if they originally contained whitespace:
# Output the remaining parameters
for param in "$@"; do
>&2 echo -e "\t$param"
done
echo "user ${user_type:-<unset>} with user id ${user_id:-<unset>} has been created with position_id ${position_id:-<unset>}"
exit 0