Utilisation de getopts pour parsingr les options après un argument non-option

J'ai un script bash comme ci-dessous dans un file nepleaks_upd.sh , que je veux exécuter en tant que ./nepleaks_upd.sh bootstrap --branch off . Impossible de le faire --branch , mais il fonctionne avec ./nepleaks_upd.sh bootstrap -b off .

 usage() { echo "Usage: $0 [prepare | up | down] [-b <on/off>]" 1>&2; exit 1; } case "$1" in bootstrap) while getopts ":b:" o; do case "${o}" in b) b=${OPTARG} if [ ${b} == "off" ]; then echo "git clone https://github.com/iPrayag/dotfiles.git" ## logic fi ;; *) echo ${o} usage ;; esac done shift $((OPTIND-1)) echo "option1 = ${o}" echo "option2 = ${b}" if [ -z "${b}" ]; then usage fi ;; up) echo "up" ##logic ;; down) echo "down" ##logic ;; *) echo "Usage: $0 {up | down} dev" exit 1 ;; esac 

Sans premier case .. in .... esac , ça marche bien. Avec le case ... in ... esac , il donne une option vide pour -b ,

 $ ./nepleaks_upd.sh bootstrap -b off option1 = ? option2 = Usage: ./nepleaks_upd.sh [bootstrap | up | down] [-b <on/off>] 

getopts commence l'parsing au premier argument et s'arrête aux premiers arguments non-option. C'est la convention standard – certains utilitaires GNU acceptent les options après les arguments, mais la chose normale est que dans somecommand foo -bar qux , -bar n'est pas analysé en tant qu'option.

Si vous voulez commencer à parsingr les options après le bootstrap , vous devez l'indiquer. getopts utilise la variable OPTIND pour se souvenir de la position dans laquelle il se trouve. OPTIND commence par la valeur 1. Pour passer le premier argument, définissez-le sur 2.

 case "$1" in bootstrap) OPTIND=2 while getopts ":b:" o; do … 

Vous pouvez également shift les arguments que vous avez déjà traités.

 subcommand=$1; shift case "$subcommand" in bootstrap) while getopts ":b:" o; do …