Save the following code as testme.sh
.
OPTS=$(getopt -o a:b:c -- "$@")
eval set -- "$OPTS"
while true; do
case "$1" in
-a )
echo "i am in a",$OPTIND
shift 2;;
-b )
echo "i am in b",$OPTIND
shift 2;;
-c )
echo "i am in c",$OPTIND
shift;;
-- )
shift;;
*)
break;;
esac
done
Run it with bash /tmp/testme.sh -a a1 -b b1 -c
.
i am in a,1
i am in b,1
i am in c,1
Now wrap all content in testme.sh as a function.
testme(){
OPTS=$(getopt -o a:b:c -- "$@")
eval set -- "$OPTS"
while true; do
case "$1" in
-a )
echo "i am in a",$OPTIND
shift 2;;
-b )
echo "i am in b",$OPTIND
shift 2;;
-c )
echo "i am in c",$OPTIND
shift;;
-- )
shift;;
*)
break;;
esac
done
}
Run it with testme -a a1 -b b1 -c
.
i am in a,
i am in b,
i am in c,
There are 2 issues confused me.
1.Why all $OPTIND
s value is 1 when to run bash /tmp/testme.sh -a a1 -b b1 -c
?
2.Why no $OPTIND
s value at all when to run testme -a a1 -b b1 -c
?
getopt
is an external command and runs in a subprocess, so it can't modify the original shell's variables. Because of this, it can't set variables like OPTIND
and OPTARG
, the way the built-in command getopts
does. It simply outputs a modified version of the argument list, which can be assigned to positional parameters with set
.
So when you use getopt
rather than getopts
, $OPTIND
is not updated. It's initialized to 1
when a shell script starts. Since your testme.sh
script never does anything that updates the variable, you get 1
every time through the loop.
When I try your testme
function, I also see 1
every time. If you're not seeing this, you must have reassigned OPTIND
before running the function. Try:
OPTIND=123
testme -a a1 -b b1 -c
and you should see
i am in a,123
i am in b,123
i am in c,123