Je veux placer une rapide invite de confirmation en haut d'un script bash potentiellement dangereux. Quelle est la façon la plus simple et la plus efficace de le faire ?
read -p "Are you sure ? " ; -n 1 -r
echo # (optionnel) déplacez-vous sur une nouvelle ligne
if [[ $REPLY =~ ^[Yy]$ ]]]
alors
# faire des choses dangereuses
fi
J'ai incorporé la suggestion de levislevis85's (merci !) et ajouté l'option -n
à read
pour accepter un caractère sans avoir à appuyer sur Enter. Vous pouvez utiliser l'une ou l'autre de ces options ou les deux.
Aussi, la forme niée pourrait ressembler à ceci :
read -p "Are you sure ? " ; -n 1 -r
echo # (optionnel) déplacer à une nouvelle ligne
si [[ ! $REPLY =~ ^[Yy]$ ]]]
alors
[[ "$0" ; = "$BASH_SOURCE" ; ]] && ; exit 1 || return 1 # gère les sorties de l'interpréteur de commandes ou de la fonction mais ne quitte pas l'interpréteur de commandes interactif
fi
Cependant, comme l'a souligné Erich, dans certaines circonstances, comme une erreur de syntaxe causée par l'exécution du script dans le mauvais shell, la forme négation pourrait permettre au script de continuer vers les "choses dangereuses". Le mode de défaillance doit privilégier l'issue la plus sûre, donc seul le premier if
, non négationné, doit être utilisé.
Explication :
La commande read
sort l'invite (-p "prompt"
) puis accepte un caractère (-n 1
) et accepte les backslashs littéralement (-r
) (sinon read
verrait le backslash comme un échappement et attendrait un second caractère). La variable par défaut dans laquelle read
stocke le résultat est $REPLY
si vous ne fournissez pas de nom comme ceci : read -p "my prompt" ; -n 1 -r my_var
L'instruction if
utilise une expression régulière pour vérifier si le caractère de $REPLY
correspond (=~
) à un "Y" ; majuscule ou minuscule. L'expression régulière utilisée ici dit "une chaîne commençant (^
) et consistant uniquement en un des caractères d'une liste de caractères dans une expression entre crochets ([Yy]
) et se terminant ($
)" ;. Les ancres (^
et $
) empêchent la correspondance de chaînes plus longues. Dans ce cas, elles aident à renforcer la limite d'un caractère fixée par la commande read
.
La forme négation utilise l'opérateur logique "not" ; (!
) pour faire correspondre (=~
) tout caractère qui n'est pas "Y" ; ou "y" ;. Une autre façon d'exprimer ceci est moins lisible et n'exprime pas aussi clairement l'intention à mon avis dans ce cas. Cependant, voici à quoi cela ressemblerait : `si [[ $REPLY =~ ^[^Yy]$ ]]``