Search code examples
bashshellgetopts

Why is the 3rd argument not parsed in getopts bash


I am trying to write a simple script to do something depending on the input arguments. Here is what I have written

#!/bin/bash
usage() { echo "Usage: $0 [-l <string>] [-p <string>] [-d <string> ]" 1>&2; exit 1; }

while getopts ":l:p:d" o; do
    case "${o}" in
        l)
            l=${OPTARG}
        echo "$l"
            ;;
        p)
            p=${OPTARG}
        echo "$p"
            ;;
        d)
            d=${OPTARG}
        echo "$d"
            ;;
        *)
            usage
            ;;
    esac
done
shift $((OPTIND-1))

if [ -z "${l}" ] && [ -z "${p}" ] && [ -z "${d}" ]; then
    usage
fi

Its able to parse the inputs given as -l and -p properly but the third input -d is not parsed.

Output:

sagar@CPU:~/$ ./play.sh -l "l is parsed" -p "p is parsed" -d "d is parsed"
l is parsed
p is parsed

This works

sagar@CPU:~/$ ./play.sh -p "p is parsed"
p is parsed

Whereas this doesn't work

sagar@CPU:~/$ ./play.sh -d "d is parsed"

Usage: ./play.sh [-l <song name>] [-p <song name>] [-d <song name> ]

What am I doing wrong here? Thanks for your help in advance.


Solution

  • You are missing : in while statement passing arguments

    #!/bin/bash
    usage() { echo "Usage: $0 [-l <string>] [-p <string>] [-d <string> ]" 1>&2; exit 1; }
    
    while getopts ":l:p:d:" o; do
        case "${o}" in
            l)
                l=${OPTARG}
            echo "$l"
                ;;
            p)
                p=${OPTARG}
            echo "$p"
                ;;
            d)
                d=${OPTARG}
            echo "$d"
                ;;
            *)
                usage
                ;;
        esac
    done
    shift $((OPTIND-1))
    
    if [ -z "${l}" ] && [ -z "${p}" ] && [ -z "${d}" ]; then
        usage
    fi
    

    Run :

    ./script.sh -l "l is parsed" -p "p is parsed" -d "d is parsed"
    

    Output :

    l is parsed
    p is parsed
    d is parsed
    

    Run :

    ./script.sh -d "d is parsed"
    

    Output :

    d is parsed