Home > OS >  Why do shortened versions of long options work with getopt?
Why do shortened versions of long options work with getopt?

Time:11-30

In the following script:

#!/usr/bin/env bash 
func_usage ()
{
cat <<EOF                                                                                                                                                                                  \
                                                                                                                                                                                            
USAGE: ${0}                                                                                                                                                                                \
                                                                                                                                                                                            
EOF                                                                                                                                                                                         
}
## Defining_Version                                                                                                                                                                         
version=1.0
## Defining_Input                                                                                                                                                                           
options=$(getopt -o "t:" -l "h,help,v,version,taxonomy:" -a -- "$@")
eval set -- "$options"
while true;do
    case $1 in
        -h|--h|-help|--help)
            func_usage
            exit 0
            ;;
        -v|--v|-version|--version)
            echo $version
            ;;
        -t|--t|-taxonomy|--taxonomy)
            echo "Option t = $2 ";
            Taxonomy_ID=$2
            echo $Taxonomy_ID
            shift
            ;;
        --)
            shift
            break;;
    esac
    shift
done
## Defining Taxonomy Default Value (in case is not provided)
TaxonomyID=${Taxonomy_ID:=9606};
echo $TaxonomyID
exit 0

The commands:

./script.sh -v
./script.sh --v
./script.sh -version
./script.sh --version

Work as expected. But what I do not understand is why the commands:

./script.sh -ver
./script.sh --ver

work at all. An equivalent unexpected behavior is also observed for the commands:

./script.sh -tax 22
./script.sh --tax 22

I would be grateful to get an explanation and/or a way to correct this unexpected behavior.

CodePudding user response:

Note that getopt is an external utility unrelated to Bash.

what I do not understand is why the commands: .. work at all.

Because getopt was designed to support it, there is no other explanation. From man getopt:

[...] Long options may be abbreviated, as long as the abbreviation is not ambiguous.

Unambiguous abbreviations of long options are converted to long options.

CodePudding user response:

Based on the comments I have received, specially from @CharlesDuffy, I have modified my code to what I believe is a more robust and compatible version. Importantly, the code below addresses the pitfalls of the original code

#!/usr/bin/env bash                                                                                                                                                                         
func_usage ()
{
cat <<EOF                                                                                                                                                                                   
USAGE: ${0}                                                                                                                                                                                 
EOF
## Defining_Version                                                                                                                                                                         
version=1.0
## Defining_Input                                                                                                                                                                           
while true;do
    case $1 in
        -h|--h|-help|--help|-\?|--\?)
            func_usage
            exit 0
            ;;
        -v|--v|-version|--version)
            echo $version
            ;;
        -t|--t|-taxonomy|--taxonomy)
            echo "Option t = $2 ";
            Taxonomy_ID=$2
            echo $Taxonomy_ID
            shift
            ;;
        --)
            shift
            break;;
        -?*)
            printf 'WARN: Unknown option (ignored): %s\n' "$1" >&2
            ;;
        *)
            break
    esac
    shift
done
TaxonomyID=${Taxonomy_ID:=9606};
echo $TaxonomyID
exit 0

The code above behaves as expected in that the commands:

./script -tax 22

Gives the warning:

WARN: Unknown option (ignored): -tax
9606

As expected

  • Related