Actuellement, j'écris un script Bash qui a les exigences suivantes:
- il devrait fonctionner sur une grande variété de plates-formes Unix / Linux
- il devrait prendre en charge les options courtes et (GNU) longues
Je sais que ce getopts
serait le moyen préféré en termes de portabilité mais AFAIK ne prend pas en charge les options longues.
getopt
prend en charge les options longues mais le BashGuide le déconseille fortement:
N'utilisez jamais getopt (1). getopt ne peut pas gérer des chaînes d'arguments vides ou des arguments avec des espaces blancs intégrés. Veuillez oublier qu'il a jamais existé.
Donc, il y a toujours la possibilité d'une analyse manuelle. Ceci est sujet aux erreurs, produit un peu de code passe-partout, et j'ai besoin de gérer les erreurs par moi-même (je suppose getopt(s)
que le traitement des erreurs par eux-mêmes).
Alors, quel serait le choix préféré dans ce cas?
bash
shell-script
options
user-interface
getopts
méthode d'aide
la source
la source
Réponses:
Si elle doit être portable sur une gamme d'unités, vous devez vous en tenir à POSIX sh. Et AFAIU là, vous n'avez tout simplement pas d'autre choix que de rouler la gestion des arguments à la main.
la source
getopt
vsgetopts
semble être un problème religieux. Quant aux arguments contregetopt
dans la FAQ Bash :"
getopt
ne peut pas gérer les chaînes d'arguments vides" semble faire référence à un problème connu avec des arguments facultatifs , qui ne semblegetopts
pas du tout prendre en charge (du moins d'après la lecturehelp getopts
de Bash 4.2.24). Deman getopt
:Je ne sais pas d'où vient le "
getopt
ne peut pas gérer les [...] arguments avec des espaces intégrés", mais testons-le:test.sh:
courir:
On dirait chèque et compagnon pour moi, mais je suis sûr que quelqu'un va montrer comment j'ai complètement mal compris la phrase. Bien sûr, le problème de la portabilité persiste; vous devrez décider combien de temps vaut la peine d'investir dans des plateformes avec un Bash plus ancien ou aucun disponible. Ma propre astuce consiste à utiliser les directives YAGNI et KISS - Développez uniquement pour les plates-formes spécifiques que vous savez que vous allez utiliser. La portabilité du code shell atteint généralement 100% lorsque le temps de développement passe à l'infini.
la source
getopt
que vous citez ici est spécifique à Linux. Notez que celagetopt
ne fait pas partiebash
, ce n'est même pas un utilitaire GNU et sous Linux est livré avec le paquet util-linux.getopt
, seul Linux AFAIK est livré avec une qui prend en charge les options longues ou les blancs dans les arguments. Les autres ne prendraient en charge que la syntaxe System V.getopt
est une commande traditionnelle qui vient de System V bien avant la sortie de Linux.getopt
n'a jamais été standardisé. Aucun de POSIX, Unix ou Linux (LSB) n'a standardisé lagetopt
commande.getopts
est spécifié dans les trois mais sans prise en charge des options longues.getopt
. C'est la saveur linux-utils comme indiqué par @ StéphaneChazelas. Il a des options héritées qui désactiveront la syntaxe décrite ci-dessus, en particulier la page de manuel indique "GETOPT_COMPATIBLE force getopt à utiliser le premier format d'appel tel que spécifié dans le SYNOPSIS". Cependant, si vous pouvez vous attendre à ce que les systèmes cibles aient ce package installé, c'est tout à fait le chemin à parcourir, car le getopt d'origine est horrible et le getopt de Bash est très limitéIl y a ce getopts_long écrit comme une fonction shell POSIX que vous pouvez intégrer dans votre script.
Notez que Linux
getopt
(deutil-linux
) fonctionne correctement lorsqu'il n'est pas en mode traditionnel et prend en charge les options longues, mais n'est probablement pas une option pour vous si vous devez être portable sur d'autres Unices.Les versions récentes de ksh93 (
getopts
) et zsh (zparseopts
) ont un support intégré pour analyser les options longues qui pourraient être une option pour vous car elles sont disponibles pour la plupart des Unices (bien que souvent non installées par défaut).Une autre option serait d'utiliser
perl
et sonGetopt::Long
module qui devrait être disponible sur la plupart des Unices de nos jours, soit en écrivant le script entierperl
soit en appelant simplement perl juste pour analyser l'option et envoyer les informations extraites au shell. Quelque chose comme:Voyez
perldoc Getopt::Long
ce qu'il peut faire et comment il diffère des autres analyseurs d'options.la source
Chaque discussion sur ce sujet met en évidence la possibilité d'écrire le code d'analyse manuellement - alors seulement vous pouvez être sûr de la fonctionnalité et de la portabilité. Je vous conseille de ne pas écrire de code que vous pouvez avoir généré et recréé par des générateurs de code open source faciles à utiliser. Utilisez Argbash , qui a été conçu pour fournir la réponse définitive à votre problème. Il s'agit d'un générateur de code bien documenté disponible sous forme d' application en ligne de commande , en ligne ou sous forme d' image Docker .
Je déconseille les bibliothèques bash, certaines d'entre elles utilisent
getopt
(ce qui rend tout à fait impossible à transporter) et il est difficile de regrouper un gigantesque blob shell illisible avec votre script.la source
Vous pouvez utiliser
getopt
sur des systèmes qui le prennent en charge et utiliser une solution de repli pour les systèmes qui ne le font pas.Par exemple,
pure-getopt
est implémenté dans Bash pur pour être un remplacement direct de GNUgetopt
.la source