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:
if echo $* | grep -e "--flag" -q
then
echo ">>>> Running with flag"
else
echo ">>>> Running without flag"
fi
Y a-t-il une meilleure façon?
Remarque: je explicitement ne pas veux lister tous les drapeaux dans un commutateur/getopt. (Dans ce cas, de telles choses deviendraient la moitié ou plus du script complet. De plus, les corps du si juste définir un ensemble de vars)
Une alternative à ce que vous faites:
if [[ $* == *--flag* ]]
Voir aussi BashFAQ/035 .
Remarque : Cela correspondra également à
--flags-off
car c'est une simple vérification de sous-chaîne.
Je vois généralement cela avec 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 drapeaux courts et longs. Dans ce cas, d'autres options sont créées à l'aide de la variable extra
.
Vous pouvez utiliser le mot clé getopt dans bash.
De http://aplawrence.com/Unix/getopts.html :
getopt
Il s'agit d'un exécutable autonome qui existe depuis longtemps. Les versions plus anciennes n'ont pas la capacité de gérer les arguments cités (foo un "ça ne marchera pas" c) et les versions qui le peuvent, le font maladroitement. Si vous utilisez une version récente de Linux, votre "getopt" peut le faire; SCO OSR5, Mac OS X 10.2.6 et FreeBSD 4.4 a une ancienne version qui n'en a pas.
L'utilisation simple de "getopt" est montrée dans ce mini-script:
#!/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
vous pouvez adopter l'approche simple et parcourir les arguments pour tester chacun d'eux pour l'égalité avec un paramètre donné (par exemple -t
).
mettez-le dans une fonction:
has_param() {
local term="$1"
shift
for arg; do
if [[ $arg == "$term" ]]; then
return 0
fi
done
return 1
}
… Et utilisez-le comme prédicat dans les expressions de test:
if has_param '-t' "$@"; then
echo "yay!"
fi
if ! has_param '-t' "$1" "$2" "$wat"; then
echo "nay..."
fi
si vous souhaitez rejeter des arguments vides, ajoutez un point de sortie en haut du corps de la boucle:
for arg; do
if [[ -z "$arg" ]]; then
return 2
fi
# ...
cela est très lisible, et ne vous donnera pas de faux positifs, comme la correspondance de modèle ou la correspondance d'expression régulière.
cela permettra également de placer des drapeaux à des positions arbitraires, par exemple, vous pouvez mettre -h
à la fin de la ligne de commande (sans préciser si c'est bon ou mauvais).
mais, plus j'y réfléchissais, plus quelque chose me dérangeait.
avec une fonction, vous pouvez prendre n'importe quelle implémentation (par exemple getopts
), et la réutiliser. encapsulation rulez!
mais même avec des commandes, cette force peut devenir un défaut. si vous l'utilisez encore et encore, vous analyserez tous les arguments à chaque fois.
ma tendance est de favoriser la réutilisation, mais je dois en être conscient. l'approche opposée serait d'analyser ces arguments une fois en haut du script, comme vous le redoutiez, et d'éviter l'analyse répétée.
vous pouvez toujours encapsuler ce boîtier de commutation, qui peut être aussi grand que vous le décidez (vous n'avez pas à lister tous les options).