Search code examples
bashshellgetopts

Bash Shell Script: How can I restrict getopts so that it only takes one type of option?


I am using getopts and for the options I want to accept just one type of letter but it can be passed multiple times. Can't figure out how to do this but it should work the way ls -l does where that ls -lllllll and ls -l -l -l -l -l all return the same thing and it only runs once.

while getopts ":abc" opt; do
        case "$opt" in
                a) echo "a"
                ;;
                b) echo "b"
                ;;
                p) echo "c"
                ;;
                ?) echo "error"
                ;;
        esac
done

so in this example, I want ./program.sh -a, ./program.sh -aaaaaaa (with any number of as), and ./program.sh -a -a -a -a to all return "a" just one time and then something like ./program.sh -ab or ./program.sh -abc or ./program.sh -a -c to return an error


Solution

  • Don't take action while parsing your options. Just record which options are seen, and take action afterwards.

    while getopts ":abc" opt; do
            case "$opt" in
                    a) A=1
                    ;;
                    b) B=1
                    ;;
                    c) C=1
                    ;;
                    ?) echo "error"
                    ;;
            esac
    done
    
    if ((A + B + C > 1)); then
        printf 'Only one of -a, -b, -c should be used.\n' >&2
        exit 1;
    fi
    
    [[ $A == 1 ]] && echo "a"
    [[ $B == 1 ]] && echo "b"
    [[ $C == 1 ]] && echo "c"