Search code examples
bashshellgetoptgetopts

Use getopts like getopt on shell


system: freebsd 9.2

I want to use getopts to parse command line. Such as

./tesh.sh -o good a.c  
can get  good.out

./tesh.sh -o a.c   
can get a.out

But in getopts there is no "option" variable. Does anyone know how to solve this problem? I found lots of webpages but no one can solve it.

here is my code

#!/bin/bash


while getopts "hs:o:" optname
do
    case "$optname" in
    "h")
        echo "Option $optname is specified"
        ;;
    "s")
        echo "Option $optname has value $OPTARG"
        ;;
    "o")    
        echo "$optname"
        ;;
    "?")
        echo "Unknown option $OPTARG"
        ;;
    ":")
    ;;
    *)
        # Should not occur
        echo "Unknown error while processing options"
        ;;
    esac
    echo "OPTIND is now $OPTIND"
done    

if i type ./test.sh -o a.c it will print echo "$optname"

and i want that if i type ./test.sh -o can also print echo "$optname"

now it will print wrong message

thx!


Solution

  • For your requirement you need not use getopts and you can use the following code to make it happen.

    If only -o is given it will be treated as a flag. If -o is givne with any value then it is treated as option.

    > cat test
    #!/bin/bash
    
    while [ $# -gt 0 ]; do
    case $1 in
            -h) echo "Option $optname is specified" ;;
            -s) VAL_S=$2; echo "Option $optname has value $VAL_S" ;shift;;
            -o) VAL_O=$2; F=$(echo $VAL_O |cut -c1);
                if [ "$F" = "-" -o -z "$F" ]; then
                    echo "-o is a flag"
                    DEFAULT=a.c
                else
                    echo "-o is a option"
                    DEFAULT=$VAL_O
                    shift
                fi
            ;;
            *) echo "Unknown option $OPTARG" ;exit ;;
    esac
    shift
    done
    

    I ran it in the possible cases.

    > ./test -o
    -o is a flag
    > ./test -o a.c
    -o is a option
    > ./test -o -h
    -o is a flag
    Option  is specified
    > ./test -o a.c -h
    -o is a option
    Option  is specified