简体   繁体   中英

getopts doesn't work when there are arguments before options

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM