web-dev-qa-db-fra.com

bash getopts avec plusieurs options obligatoires

Est-il possible d'utiliser getopts pour traiter plusieurs options ensemble? Par exemple, myscript -iR ou myscript -irv.

En outre, j'ai une situation où, basé sur un script de condition, aurait besoin d'une option obligatoire. Par exemple, si l'argument du script est un répertoire, je devrai spécifier l'option -R ou -r avec toutes les autres options (myscript -iR mydir ou myscript -ir mydir ou myscript -i -r mydir ou myscript -i -R mydir), en cas de fichier uniquement -i est suffisant (myscript -i myfile).

J'ai essayé de chercher, mais je n'ai obtenu aucune réponse.

37
Ramesh Samane

Vous pouvez concaténer les options que vous fournissez et getopts les séparera. Dans votre instruction case, vous gérerez chaque option individuellement.

Vous pouvez définir un indicateur lorsque des options sont vues et vérifier que les "options" obligatoires (!) Sont présentes une fois la boucle getopts terminée.

Voici un exemple:

#!/bin/bash
rflag=false
small_r=false
big_r=false

usage () { echo "How to use"; }

options=':ij:rRvh'
while getopts $options option
do
    case "$option" in
        i  ) i_func;;
        j  ) j_arg=$OPTARG;;
        r  ) rflag=true; small_r=true;;
        R  ) rflag=true; big_r=true;;
        v  ) v_func; other_func;;
        h  ) usage; exit;;
        \? ) echo "Unknown option: -$OPTARG" >&2; exit 1;;
        :  ) echo "Missing option argument for -$OPTARG" >&2; exit 1;;
        *  ) echo "Unimplemented option: -$OPTARG" >&2; exit 1;;
    esac
done

if ((OPTIND == 1))
then
    echo "No options specified"
fi

shift $((OPTIND - 1))

if (($# == 0))
then
    echo "No positional arguments specified"
fi

if ! $rflag && [[ -d $1 ]]
then
    echo "-r or -R must be included when a directory is specified" >&2
    exit 1
fi

Cela représente une implémentation de référence complète d'une fonction getopts, mais n'est qu'une esquisse d'un script plus grand.

92
Dennis Williamson