• # Les grands esprits toussa...

    Posté par . En réponse à la dépêche Bash Argsparse : mieux gérer sa ligne de commande dans ses scripts.. Évalué à 3.

    Amusant, je suis en ce moment également en train de chercher une alternative plus souple à getopts, dans une autre approche cependant: je cherche quelque chose de compact et POSIX. Comme j'aime beaucoup les interfaces BSD/POSIX (à base d'options courtes exclusivement), voici à quoi je suis arrivé:

    getopt () {
     local opt=${1:-'X].[X'}; shift 1
     awk 'BEGIN{ for (i=x=1; i < ARGC; i++) {
     s = ARGV[i]
     if (X || ! sub(/^-/,"",s)) {
     LT[j++] = i-x; x=i
     continue
     }
     (s == "-") && (X=1) && s=""
     while (o=substr(s,1,1)) {
     if (o ~ /^['$opt']/) {
     print (s == o) ? (o""++i) : (o i"#-*" o)
     if (i < ARGC)
     break
     print "!"o # will be the last argument.
     }
     sub(/./,"",s); print o
     }
     }
     exit (E = (j>0) ? 0 : 1)
     }
     END{ print "--"; for (i=0; i < j; i++) print LT[i]; exit E }' "$@"
    }
    t=0 # type d'argument: 0=option; 1=littéral
    tog=0
    for arg in $(getopt xyz "$@"); do
     case "$t$arg" in
     1*) shift $arg; echo "argument: \"1ドル\"";;
     0--) t=1; continue;;
     0h) echo "aide."; exit 0;;
     0a) echo "interrupteur: \"$arg\" (tog=1)"; tog=1;;
     0b) echo "interrupteur: \"$arg\" (tog=0)"; tog=0;;
     0x*) eval x=\${${arg#x}}; echo "definition: x=\"$x\"";;
     0y*) eval y=\${${arg#y}}; echo "definition: y=\"$y\"";;
     0z*) eval z=\${${arg#z}}; echo "definition: z=\"$z\"";;
     0!?*) echo "${arg#!}: requiert un argument."; exit 1;;
     *) echo "$arg: option inconnue"; exit 1
     esac
    done

    Qui à l'exécution nous donne ceci:

    $ dash getopt.sh toto -bax "lili lulu" -ylolo titi "tata tutu" -- -a -bz lala
    interrupteur: "b" (tog=0)
    interrupteur: "a" (tog=1)
    definition: x="lili lulu"
    definition: y="lolo"
    argument: "toto"
    argument: "titi"
    argument: "tata tutu"
    argument: "-a"
    argument: "-bz"
    argument: "lala"
    

    C'est bien sûr loin d'être aussi complet que ce qui est proposé par argsparse, mais c'est portable et pour ma part je préfère avoir la pleine maîtrise de l'interface (dans la gestion des erreurs en particulier).