web-dev-qa-db-fra.com

Comment puis-je inviter un utilisateur à confirmer dans un script bash?

Je veux mettre un rapide "êtes-vous sûr?" Demander confirmation en haut d’un script bash potentiellement dangereux, quel est le moyen le plus simple et le plus simple de le faire?

539
Tom
_read -p "Are you sure? " -n 1 -r
echo    # (optional) move to a new line
if [[ $REPLY =~ ^[Yy]$ ]]
then
    # do dangerous stuff
fi
_

J'ai incorporé la suggestion de levislevis85 (merci!) Et ajouté l'option _-n_ à read pour accepter un caractère sans avoir besoin d'appuyer sur Enter. Vous pouvez utiliser un ou les deux.

En outre, la forme refusée pourrait ressembler à ceci:

_read -p "Are you sure? " -n 1 -r
echo    # (optional) move to a new line
if [[ ! $REPLY =~ ^[Yy]$ ]]
then
    [[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1 # handle exits from Shell or function but don't exit interactive Shell
fi
_

Cependant, comme l'a souligné Erich, dans certaines circonstances, telles qu'une erreur de syntaxe provoquée par l'exécution du script dans un shell incorrect, le formulaire refusé pourrait permettre au script de continuer avec le "contenu dangereux". Le mode de défaillance devrait favoriser le résultat le plus sûr, de sorte que seul le premier if non annulé soit utilisé.

Explication:

La commande read affiche l'invite (_-p "Prompt"_) puis accepte un caractère (_-n 1_) et accepte les barres obliques inverses littéralement (_-r_) (sinon read verrait la barre oblique inverse. comme une évasion et attendre un deuxième personnage). La variable par défaut de read pour stocker le résultat est _$REPLY_ si vous n'indiquez pas un nom comme celui-ci: _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 indique "une chaîne commençant par _^_) et consistant uniquement en l'un d'une liste de caractères d'une expression entre crochets (_[Yy]_) et se terminant (_$_)". Les ancres (_^_ et _$_) empêchent la correspondance de chaînes plus longues. Dans ce cas, ils aident à renforcer la limite d'un caractère définie dans la commande read.

La forme refusée utilise l'opérateur "pas" logique (_!_) pour faire correspondre (_=~_) à tout caractère autre que "Y" ou "y". Une autre façon d’exprimer cela est moins lisible et n’exprime pas aussi clairement l’intention selon mon opinion dans ce cas. Cependant, voici à quoi cela ressemblerait: _if [[ $REPLY =~ ^[^Yy]$ ]]_

851
Dennis Williamson

cas d'utilisation/esac.

read -p "Continue (y/n)?" choice
case "$choice" in 
  y|Y ) echo "yes";;
  n|N ) echo "no";;
  * ) echo "invalid";;
esac

avantage:

  1. plus propre
  2. peut utiliser "OU" condition plus facile
  3. peut utiliser une plage de caractères, par exemple [yY] [eE] [sS] pour accepter le mot "oui", l'un quelconque de ses caractères pouvant être en minuscule ou en majuscule.
157
ghostdog74

Essayez le read Shell intégré:

read -p "Continue (y/n)?" CONT
if [ "$CONT" = "y" ]; then
  echo "yaaa";
else
  echo "booo";
fi
31
Adam Hupp

De cette façon, vous obtenez "y" "oui" ou "Entrée"

 read -r -p "Are you sure? [Y/n]" response
 response=${response,,} # tolower
 if [[ $response =~ ^(yes|y| ) ]] || [[ -z $response ]]; then
    your-action-here
 fi

Si vous utilisez zsh, essayez ceci:

read "response?Are you sure ? [Y/n] "
response=${response:l} #tolower
if [[ $response =~ ^(yes|y| ) ]] || [[ -z $response ]]; then
    your-action-here
fi
31
SergioAraujo

Voici la fonction que j'utilise:

function ask_yes_or_no() {
    read -p "$1 ([y]es or [N]o): "
    case $(echo $REPLY | tr '[A-Z]' '[a-z]') in
        y|yes) echo "yes" ;;
        *)     echo "no" ;;
    esac
}

Et un exemple d'utilisation:

if [[ "no" == $(ask_yes_or_no "Are you sure?") || \
      "no" == $(ask_yes_or_no "Are you *really* sure?") ]]
then
    echo "Skipped."
    exit 0
fi

# Do something really dangerous...
  • La sortie est toujours "oui" ou "non"
  • C'est "non" par défaut
  • Tout sauf "y" ou "oui" renvoie "non", donc c'est assez sûr pour un script bash dangereux
  • Et c'est insensible à la casse, "Y", "Oui" ou "OUI" fonctionne comme "oui".

J'espère que tu aimes,
À votre santé!

20

C'est ce que j'ai trouvé ailleurs, existe-t-il une meilleure version possible?

read -p "Are you sure you wish to continue?"
if [ "$REPLY" != "yes" ]; then
   exit
fi
15
Tom
[[ -f ./${sname} ]] && read -p "File exists. Are you sure? " -n 1

[[ ! $REPLY =~ ^[Yy]$ ]] && exit 1

utilisé cela dans une fonction pour rechercher un fichier existant et Demander avant remplacement.

6
Bradley
#!/bin/bash
echo Please, enter your name
read NAME
echo "Hi $NAME!"
if [ "x$NAME" = "xyes" ] ; then
 # do something
fi

C’est un court script à lire en bash et qui renvoie les résultats.

4
Philip Schlump

qnd: utiliser

read VARNAME
echo $VARNAME

pour une réponse d'une ligne sans support readline. Puis testez $ VARNAME comme vous le souhaitez.

2
zen
echo are you sure?
read x
if [ "$x" = "yes" ]
then
  # do the dangerous stuff
fi
2
kingsindian