bashgetopts

BASH - Options included in $@


I have a script that processes files and can take multiple file arguments:

sh remove_engine file1 #single arg

sh remove_engine file1 file2 #multiple file arg

At the top of the script, I gather these together with $@ in order to loop over them.

The problem is that I'm also going to use options (along with getopts)...

sh remove_engine -ri file1 file2

...and $@ now returns

-rvi file1 file2

and the rest of the script takes -ri as a file name.

Also near the top of the script, I have a while loop with getopts

while getopts :rvi opt
do
    case"$opt" in
    v)      verbose="true";;
    i)      interactive="true";;
    r)      recursive="true";;
   [?])     echo "Usage..."
            exit;;
    esac
done

How do I parse the options and then separate out the arguments from the options?


Solution

  • From man bash:

    When the end of options is encountered, getopts exits with a return value greater than zero. OPTINDis set to the index of the first non-option argument, and name is set to ?.

    So the full code is:

    #!/bin/bash
    
    while getopts :rvi opt; do
      case $opt in
        v) verbose=true ;;
        i) interactive=true ;;
        r) recursive=true ;;
        *) echo "Usage..."; exit 1 ;;
      esac
    done
    
    shift $((OPTIND-1))  # remove all the OPTIND-1 parsed arguments from "$@"
    
    echo "$@"  # use the remaining arguments