2010-05-20 3 views
23

Au milieu d'un script, je veux vérifier si un drapeau donné a été passé sur la ligne de commande. Ce qui suit fait ce que je veux, mais semble laid:Correct façon de vérifier un drapeau de ligne de commande dans bash

if echo $* | grep -e "--flag" -q 
then 
    echo ">>>> Running with flag" 
else 
    echo ">>>> Running without flag" 
fi 

Y at-il une meilleure façon?

Remarque: Je explicitement ne pas voulez lister tous les indicateurs dans un commutateur/getopt. (Dans ce cas, toutes ces choses deviendraient la moitié ou plus du script complet, ainsi que les corps du si juste définir un ensemble de variables)

Répondre

4

Vous pouvez utiliser le mot-clé getopt dans bash.

De http://aplawrence.com/Unix/getopts.html:

getopt

C'est un exécutable autonome qui a été autour depuis longtemps. Les anciennes versions n'ont pas la capacité de gérer les arguments entre guillemets (foo a "ce ne fonctionnera pas" c) et les versions qui le peuvent, le font maladroitement. Si vous êtes exécutant une version récente de Linux, votre "getopt" peut le faire; SCO OSR5, Mac OS X 10.2.6 et FreeBSD 4.4 ont une version plus ancienne qui ne le fait pas.

L'utilisation simple de "getopt" apparaît dans ce mini-scriptum:

#!/bin/bash 
echo "Before getopt" 
for i 
do 
    echo $i 
done 
args=`getopt abc:d $*` 
set -- $args 
echo "After getopt" 
for i 
do 
    echo "-->$i" 
done 
+0

Il est préférable d'utiliser le 'getopts' intégré plutôt que le' getopt' externe. –

+0

@Dennis: 'getopts' prend en charge les noms d'option longs comme' --flag'? – indiv

+0

@indiv: Oh, désolé, j'ai négligé cette exigence. J'utiliserais une instruction 'case' avant d'utiliser' getopt'. Voir [this] (http://aplawrence.com/Unix/getopts.html) pour une comparaison de 'getopt' et' getopts'. –

4

Je vois généralement ce fait une déclaration de cas. Voici un extrait du script git-repack:

while test $# != 0 
do 
    case "$1" in 
    -n) no_update_info=t ;; 
    -a) all_into_one=t ;; 
    -A) all_into_one=t 
     unpack_unreachable=--unpack-unreachable ;; 
    -d) remove_redundant=t ;; 
    -q) GIT_QUIET=t ;; 
    -f) no_reuse=--no-reuse-object ;; 
    -l) local=--local ;; 
    --max-pack-size|--window|--window-memory|--depth) 
     extra="$extra $1=$2"; shift ;; 
    --) shift; break;; 
    *) usage ;; 
    esac 
    shift 
done 

Notez que cela vous permet de vérifier les deux drapeaux courts et longs. D'autres options sont construites en utilisant la variable extra dans ce cas.

+0

Je pense que vous devez supprimer la dernière instruction 'shift', juste après le 'esac'. Au moins sur ma machine ça ne marche pas si c'est présent. –

37

Une alternative à ce que vous faites:

if [[ $* == *--flag* ]] 

Voir aussi BashFAQ/035.

+0

Cela ne ramènera-t-il pas aussi de faux positifs? par exemple. Si vous chechez pour '* -f *', cela correspondra à '--force',' -fish', '--update-files',' -w-t-f'etc – nathanchere

+0

@nathanchere: le choix rigoureux de la chaîne de correspondance est important. Notez que votre exemple permet toutes les correspondances que vous listez mais la mienne laisse beaucoup moins de possibilités de faux positifs. Compte tenu de l'exigence du PO pour une solution simple, la mine convient très bien. Sinon, utilisez getopt ou getopts. –

+0

Exactement mon point.Le mien était un exemple intentionnellement simplifié, mais démontre toujours le même problème avec le vôtre. par exemple. Si vous utilisez '* - flag *', vous devrez faire correspondre '--flag',' --flags-off', etc. C'est donc une solution bâclée – nathanchere

Questions connexes