Assuming that your mandatory argument appears last, then you should try the following code: [comments inline]
OPTIND=1
while getopts "b:a:" option
do
case "${option}"
in
b) MERGE_BRANCH=${OPTARG};;
a) ACTION=${OPTARG};;
esac
done
# reset positional arguments to include only those that have not
# been parsed by getopts
shift $((OPTIND-1))
[ "$1" = "--" ] && shift
# test: there is at least one more argument left
(( 1 <= ${#} )) || { echo "missing mandatory argument" 2>&1 ; exit 1; };
echo "$1"
echo "$MERGE_BRANCH"
echo "$ACTION"
The result:
~$ ./test.sh -b B -a A test
test
B
A
~$ ./tes.sh -b B -a A
missing mandatory argument
If you really want the mandatory argument to appear first, then you can do the following thing:
MANDATORY="${1}"
[[ "${MANDATORY}" =~ -.* ]] && { echo "missing or invalid mandatory argument" 2>&1; exit 1; };
shift # or, instead of using `shift`, you can set OPTIND=2 in the next line
OPTIND=1
while getopts "b:a:" option
do
case "${option}"
in
b) MERGE_BRANCH=${OPTARG};;
a) ACTION=${OPTARG};;
esac
done
# reset positional arguments to include only those that have not
# been parsed by getopts
shift $((OPTIND-1))
[ "$1" = "--" ] && shift
echo "$MANDATORY"
echo "$MERGE_BRANCH"
echo "$ACTION"
The result is the following:
~$ ./test.sh test -b B -a A
test
B
A
~$ ./tes.sh -b B -a A
missing or invalid mandatory argument