When I run the command like this :
$: ./script -r f1 f2
:
it detects the "-r" flag and sets the recursive flag to 1.
$: ./script directory/ -r
:
getopts
doesn't detect the -r
flag at all. So inside the case statement it never detects -r
flag and so the while loop doens't even run at all. how to fix this ?
RECURSIVE_FLAG=0
while getopts ":rR" opt ; do
echo " opt = $opt"
set -x
case "$opt" in
r) RECURSIVE_FLAG=1 ;;
R) RECURSIVE_FLAG=1 ;;
:)echo "not working" ;;
*)echo "Testing *" ;;
esac
done
It has nothing to do with slash. getopts
stops processing options when it gets to the first argument that doesn't begin with -
. This is the documented behavior:
When the end of options is encountered,
getopts
exits with a return value greater than zero.OPTIND
is set to the index of the first non-option argument, and name is set to?
.
Your claim that it works when you use
./script f1 f2 -r
is simply wrong. I added echo $RECURSIVE_FLAG
to the end of your script, and when I ran it that way it echoed 0
.
If you want to allow a more liberal syntax, with options after filenames (like GNU rm
) you'll need to do some argument parsing of your own. Put your getopts
loop inside another loop. When the getopts
loop finishes, you can do:
# Find next option argument
while [[ $OPTIND <= $# && ${!OPTIND} != -* ]]; do
((OPTIND++))
done
# Stop when we've run out of arguments
if [[ $OPTIND > $# ]]; then
break
fi