web-dev-qa-db-fra.com

Comment demander une entrée Oui / Non / Annuler dans un script Linux Shell?

Je souhaite suspendre la saisie dans un script Shell et demander à l'utilisateur de choisir. La question type de type 'Oui, Non ou Annuler'. Comment puis-je accomplir cela dans une invite bash typique?

1310
Myrddin Emrys

La méthode la plus simple et la plus largement disponible pour obtenir les entrées de l'utilisateur à l'invite du shell est la commande read . Le meilleur moyen d’illustrer son utilisation est une simple démonstration:

while true; do
    read -p "Do you wish to install this program?" yn
    case $yn in
        [Yy]* ) make install; break;;
        [Nn]* ) exit;;
        * ) echo "Please answer yes or no.";;
    esac
done

Une autre méthode, indiquée par Steven Huwig, est la commande select de Bash. Voici le même exemple utilisant select:

echo "Do you wish to install this program?"
select yn in "Yes" "No"; do
    case $yn in
        Yes ) make install; break;;
        No ) exit;;
    esac
done

Avec select, vous n'avez pas besoin d'assainir l'entrée. Elle affiche les choix disponibles et vous tapez un nombre correspondant à votre choix. Il effectue également une boucle automatique. Par conséquent, il n'est pas nécessaire de procéder à une nouvelle tentative de boucle while true si elles fournissent une entrée non valide.

Aussi, s'il vous plaît consulter le excellente réponse par F. Hauri.

1465
Myrddin Emrys

Au moins cinq réponses à une question générique.

Cela dépend de

  • posix conforme: pourrait fonctionner sur des systèmes pauvres avec des environnements génériques Shell
  • bash spécifique: utiliser ce qu'on appelle bashismes

et si tu veux

  • simple question/réponse "en ligne" (solutions génériques)
  • jolies interfaces formatées, comme ncurses ou plus graphique en utilisant libgtk ou libqt ...
  • utiliser une puissante capacité d'historique readline

1. Solutions génériques POSIX

Vous pouvez utiliser la commande read, suivie de _if ... then ... else_:

_echo -n "Is this a good question (y/n)? "
read answer
_
_# if echo "$answer" | grep -iq "^y" ;then
_
_if [ "$answer" != "${answer#[Yy]}" ] ;then
    echo Yes
else
    echo No
fi
_

(Merci à commentaire d'Adam Katz : Remplacé le test ci-dessus par un autre qui est plus portable et évite une fourchette :)

POSIX, mais touche unique

Mais si vous ne voulez pas que l'utilisateur ait à frapper Return, vous pourriez écrire:

( édité: Comme le suggère @JonathanLeffler à juste titre, la configuration de save stty pourrait être meilleure que de simplement la forcer à sane.)

_echo -n "Is this a good question (y/n)? "
old_stty_cfg=$(stty -g)
stty raw -echo ; answer=$(head -c 1) ; stty $old_stty_cfg # Careful playing with stty
if echo "$answer" | grep -iq "^y" ;then
    echo Yes
else
    echo No
fi
_

Remarque: Ceci a été testé sous sh , bash , ksh , tiret et busybox !

Idem, mais en attente explicite de y ou n:

_#/bin/sh
echo -n "Is this a good question (y/n)? "
old_stty_cfg=$(stty -g)
stty raw -echo
answer=$( while ! head -c 1 | grep -i '[ny]' ;do true ;done )
stty $old_stty_cfg
if echo "$answer" | grep -iq "^y" ;then
    echo Yes
else
    echo No
fi
_

Utiliser des outils dédiés

De nombreux outils ont été créés à l'aide de libncurses, libgtk, libqt ou d'autres bibliothèques graphiques. Par exemple, en utilisant whiptail:

_if whiptail --yesno "Is this a good question" 20 60 ;then
    echo Yes
else
    echo No
fi
_

Selon votre système, vous devrez peut-être remplacer whiptail par un autre outil similaire:

_dialog --yesno "Is this a good question" 20 60 && echo Yes

gdialog --yesno "Is this a good question" 20 60 && echo Yes

kdialog --yesno "Is this a good question" 20 60 && echo Yes
_

où _20_ est la hauteur de la boîte de dialogue en nombre de lignes et _60_ est la largeur de la boîte de dialogue. Ces outils ont tous la syntaxe near same.

_DIALOG=whiptail
if [ -x /usr/bin/gdialog ] ;then DIALOG=gdialog ; fi
if [ -x /usr/bin/xdialog ] ;then DIALOG=xdialog ; fi
...
$DIALOG --yesno ...
_

2. Solutions spécifiques Bash

Basic en ligne méthode

_read -p "Is this a good question (y/n)? " answer
case ${answer:0:1} in
    y|Y )
        echo Yes
    ;;
    * )
        echo No
    ;;
esac
_

Je préfère utiliser case pour pouvoir même tester _yes | ja | si | oui_ si nécessaire ...

en ligne avec touche unique fonctionnalité

Sous bash, nous pouvons spécifier la longueur de l'entrée souhaitée pour la commande read:

_read -n 1 -p "Is this a good question (y/n)? " answer
_

Sous bash, la commande read accepte un paramètre timeout, ce qui peut être utile.

_read -t 3 -n 1 -p "Is this a good question (y/n)? " answer
[ -z "$answer" ] && answer="Yes"  # if 'yes' have to be default choice
_

Quelques astuces pour outils dédiés

Boîtes de dialogue plus sophistiquées, au-delà des simples yes - no:

_dialog --menu "Is this a good question" 20 60 12 y Yes n No m Maybe
_

Barre de progression:

_dialog --gauge "Filling the tank" 20 60 0 < <(
    for i in {1..100};do
        printf "XXX\n%d\n%(%a %b %T)T progress: %d\nXXX\n" $i -1 $i
        sleep .033
    done
) 
_

Petite démo:

_#!/bin/sh
while true ;do
    [ -x "$(which ${DIALOG%% *})" ] || DIALOG=dialog
    DIALOG=$($DIALOG --menu "Which tool for next run?" 20 60 12 2>&1 \
            whiptail       "dialog boxes from Shell scripts" >/dev/tty \
            dialog         "dialog boxes from Shell with ncurses" \
            gdialog        "dialog boxes from Shell with Gtk" \
            kdialog        "dialog boxes from Shell with Kde" ) || exit
    clear;echo "Choosed: $DIALOG."
    for i in `seq 1 100`;do
        date +"`printf "XXX\n%d\n%%a %%b %%T progress: %d\nXXX\n" $i $i`"
        sleep .0125
      done | $DIALOG --gauge "Filling the tank" 20 60 0
    $DIALOG --infobox "This is a simple info box\n\nNo action required" 20 60
    sleep 3
    if $DIALOG --yesno  "Do you like this demo?" 20 60 ;then
        AnsYesNo=Yes; else AnsYesNo=No; fi
    AnsInput=$($DIALOG --inputbox "A text:" 20 60 "Text here..." 2>&1 >/dev/tty)
    AnsPass=$($DIALOG --passwordbox "A secret:" 20 60 "First..." 2>&1 >/dev/tty)
    $DIALOG --textbox /etc/motd 20 60
    AnsCkLst=$($DIALOG --checklist "Check some..." 20 60 12 \
        Correct "This demo is useful"        off \
        Fun        "This demo is Nice"        off \
        Strong        "This demo is complex"        on 2>&1 >/dev/tty)
    AnsRadio=$($DIALOG --radiolist "I will:" 20 60 12 \
        " -1" "Downgrade this answer"        off \
        "  0" "Not do anything"                on \
        " +1" "Upgrade this anser"        off 2>&1 >/dev/tty)
    out="Your answers:\nLike: $AnsYesNo\nInput: $AnsInput\nSecret: $AnsPass"
    $DIALOG --msgbox "$out\nAttribs: $AnsCkLst\nNote: $AnsRadio" 20 60
  done
_

Plus échantillon? Regardez tilisation de whiptail pour choisir un périphérique USB et sélecteur de stockage amovible USB: USBKeyChooser

5. Utiliser l'historique de readline

Exemple:

_#!/bin/bash

set -i
HISTFILE=~/.myscript.history
history -c
history -r

myread() {
    read -e -p '> ' $1
    history -s ${!1}
}
trap 'history -a;exit' 0 1 2 3 6

while myread line;do
    case ${line%% *} in
        exit )  break ;;
        *    )  echo "Doing something with '$line'" ;;
      esac
  done
_

Cela créera un fichier _.myscript.history_ dans votre répertoire _$HOME_ que vous ne pourriez utiliser les commandes d'historique de readline, comme UpDownCtrl+r et d'autres.

473
F. Hauri
echo "Please enter some input: "
read input_variable
echo "You entered: $input_variable"
344
Pistos

Vous pouvez utiliser la commande read intégrée; Utilisez l’option -p pour demander à l’utilisateur une question.

Depuis BASH4, vous pouvez maintenant utiliser -i pour suggérer une réponse. Il suffit donc à l'utilisateur d'appuyer sur return pour le saisir:

read -e -p "Enter the path to the file: " -i "/usr/local/etc/" FILEPATH
echo $FILEPATH

(Mais n'oubliez pas d'utiliser l'option "readline" -e pour autoriser l'édition de lignes avec les touches fléchées)

Si vous voulez une logique "oui/non", vous pouvez faire quelque chose comme ceci:

read -e -p "
List the content of your home dir ? [Y/n] " YN

[[ $YN == "y" || $YN == "Y" || $YN == "" ]] && ls -la ~/
160
yPhil

Bash a select à cet effet.

select result in Yes No Cancel
do
    echo $result
done
103
Steven Huwig
read -p "Are you alright? (y/n) " RESP
if [ "$RESP" = "y" ]; then
  echo "Glad to hear it"
else
  echo "You need more bash programming"
fi
55
serg

Voici quelque chose que j'ai mis en place:

#!/bin/sh

promptyn () {
    while true; do
        read -p "$1 " yn
        case $yn in
            [Yy]* ) return 0;;
            [Nn]* ) return 1;;
            * ) echo "Please answer yes or no.";;
        esac
    done
}

if promptyn "is the sky blue?"; then
    echo "yes"
else
    echo "no"
fi

Je suis débutant, alors prenez ceci avec un grain de sel, mais cela semble fonctionner.

34
mpen
inquire ()  {
  echo  -n "$1 [y/n]? "
  read answer
  finish="-1"
  while [ "$finish" = '-1' ]
  do
    finish="1"
    if [ "$answer" = '' ];
    then
      answer=""
    else
      case $answer in
        y | Y | yes | YES ) answer="y";;
        n | N | no | NO ) answer="n";;
        *) finish="-1";
           echo -n 'Invalid response -- please reenter:';
           read answer;;
       esac
    fi
  done
}

... other stuff

inquire "Install now?"

...
30
SumoRunner

Tu veux:

  • Commandes intégrées Bash (c'est-à-dire portables)
  • Vérifier l'ATS
  • Réponse par défaut
  • Temps libre
  • Question colorée

Fragment

do_xxxx=y                      # In batch mode => Default is Yes
[[ -t 0 ]] &&                  # If TTY => Prompt the question
read -n 1 -p $'\e[1;32m
Do xxxx? (Y/n)\e[0m ' do_xxxx  # Store the answer in $do_xxxx
if [[ $do_xxxx =~ ^(y|Y|)$ ]]  # Do if 'y' or 'Y' or empty
then
    xxxx
fi

Des explications

  • [[ -t 0 ]] && read ... => Commande d'appel read si TTY
  • read -n 1 => Attendre un caractère
  • $'\e[1;32m ... \e[0m ' => Imprimer en vert
    (le vert convient, car il est lisible sur les fonds blancs et noirs)
  • [[ $do_xxxx =~ ^(y|Y|)$ ]] => bash regex

Timeout => La réponse par défaut est No

do_xxxx=y
[[ -t 0 ]] && {                   # Timeout 5 seconds (read -t 5)
read -t 5 -n 1 -p $'\e[1;32m
Do xxxx? (Y/n)\e[0m ' do_xxxx ||  # read 'fails' on timeout
do_xxxx=n ; }                     # Timeout => answer No
if [[ $do_xxxx =~ ^(y|Y|)$ ]]
then
    xxxx
fi
27
olibre

Le moyen le plus simple d'y parvenir avec le moins de lignes possible est le suivant:

read -p "<Your Friendly Message here> : y/n/cancel" CONDITION;

if [ "$CONDITION" == "y" ]; then
   # do something here!
fi

La if n'est qu'un exemple: c'est à vous de décider comment gérer cette variable.

23
Apurv Nerlekar

Utilisez la commande read:

echo Would you like to install? "(Y or N)"

read x

# now check if $x is "y"
if [ "$x" = "y" ]; then
    # do something here!
fi

et puis toutes les autres choses dont vous avez besoin

18
ThatLinuxGuy

Cette solution lit un seul caractère et appelle une fonction sur une réponse oui.

read -p "Are you sure? (y/n) " -n 1
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
    do_something      
fi
17
Dennis
read -e -p "Enter your choice: " choice

L'option -e permet à l'utilisateur de modifier l'entrée à l'aide des touches fléchées.

Si vous souhaitez utiliser une suggestion comme entrée:

read -e -i "yes" -p "Enter your choice: " choice

L'option -i imprime une entrée suggestive.

12
Jahid

Vous pouvez utiliser la valeur par défaut REPLY sur un read, convertir en minuscule et la comparer à un ensemble de variables avec une expression.
Le script prend également en charge ja/si/oui

read -rp "Do you want a demo? [y/n/c] "

[[ ${REPLY,,} =~ ^(c|cancel)$ ]] && { echo "Selected Cancel"; exit 1; }

if [[ ${REPLY,,} =~ ^(y|yes|j|ja|s|si|o|oui)$ ]]; then
   echo "Positive"
fi
12
Walter A

Désolé pour avoir posté sur un si vieux post. Il y a quelques semaines, je rencontrais un problème similaire. Dans mon cas, j'avais besoin d'une solution qui fonctionnait également dans un script d'installation en ligne, par exemple: curl -Ss https://raw.github.com/_____/installer.sh | bash

Utiliser read yesno < /dev/tty me convient parfaitement:

echo -n "These files will be uploaded. Is this ok? (y/n) "
read yesno < /dev/tty

if [ "x$yesno" = "xy" ];then

   # Yes
else

   # No
fi

J'espère que ça aide quelqu'un.

10
user9869932

Touche unique seulement

Voici une approche plus longue, mais réutilisable et modulaire:

  • Renvoie 0 = yes et 1 = no
  • Aucune pression requise pour entrer - juste un seul caractère
  • Peut appuyer enter accepter le choix par défaut
  • Peut désactiver le choix par défaut pour forcer une sélection
  • Fonctionne pour zsh et bash.

La valeur par défaut est "non" lorsque vous appuyez sur Entrée.

Notez que la N est en majuscule. Ici, appuyez sur Entrée pour accepter la valeur par défaut:

$ confirm "Show dangerous command" && echo "rm *"
Show dangerous command [y/N]?

Notez également que [y/N]? a été ajouté automatiquement. Le "non" par défaut est accepté, ainsi rien n'est renvoyé.

Ré-invite jusqu'à ce qu'une réponse valide soit donnée:

$ confirm "Show dangerous command" && echo "rm *"
Show dangerous command [y/N]? X
Show dangerous command [y/N]? y
rm *

La valeur par défaut est "oui" lorsque vous appuyez sur Entrée.

Notez que la Y est en majuscule:

$ confirm_yes "Show dangerous command" && echo "rm *"
Show dangerous command [Y/n]?
rm *

Ci-dessus, j'ai juste appuyé sur Entrée, donc la commande a été exécutée.

Pas de défaut sur enter - nécessite y ou n

$ get_yes_keypress "Here you cannot press enter. Do you like this [y/n]? "
Here you cannot press enter. Do you like this [y/n]? k
Here you cannot press enter. Do you like this [y/n]?
Here you cannot press enter. Do you like this [y/n]? n
$ echo $?
1

Ici, 1 ou false a été renvoyé. Notez qu'avec cette fonction de niveau inférieur, vous devrez fournir votre propre invite [y/n]?.

Code

# Read a single char from /dev/tty, prompting with "$*"
# Note: pressing enter will return a null string. Perhaps a version terminated with X and then remove it in caller?
# See https://unix.stackexchange.com/a/367880/143394 for dealing with multi-byte, etc.
function get_keypress {
  local REPLY IFS=
  >/dev/tty printf '%s' "$*"
  [[ $ZSH_VERSION ]] && read -rk1  # Use -u0 to read from STDIN
  # See https://unix.stackexchange.com/q/383197/143394 regarding '\n' -> ''
  [[ $BASH_VERSION ]] && </dev/tty read -rn1
  printf '%s' "$REPLY"
}

# Get a y/n from the user, return yes=0, no=1 enter=$2
# Prompt using $1.
# If set, return $2 on pressing enter, useful for cancel or defualting
function get_yes_keypress {
  local Prompt="${1:-Are you sure [y/n]? }"
  local enter_return=$2
  local REPLY
  # [[ ! $Prompt ]] && Prompt="[y/n]? "
  while REPLY=$(get_keypress "$Prompt"); do
    [[ $REPLY ]] && printf '\n' # $REPLY blank if user presses enter
    case "$REPLY" in
      Y|y)  return 0;;
      N|n)  return 1;;
      '')   [[ $enter_return ]] && return "$enter_return"
    esac
  done
}

# Credit: http://unix.stackexchange.com/a/14444/143394
# Prompt to confirm, defaulting to NO on <enter>
# Usage: confirm "Dangerous. Are you sure?" && rm *
function confirm {
  local Prompt="${*:-Are you sure} [y/N]? "
  get_yes_keypress "$Prompt" 1
}    

# Prompt to confirm, defaulting to YES on <enter>
function confirm_yes {
  local Prompt="${*:-Are you sure} [Y/n]? "
  get_yes_keypress "$Prompt" 0
}
8
Tom Hale

Pour obtenir une jolie boîte de saisie de type ncurses, utilisez la commande dialog comme ceci:

#!/bin/bash
if (dialog --title "Message" --yesno "Want to do something risky?" 6 25)
# message box will have the size 25x6 characters
then 
    echo "Let's do something risky"
    # do something risky
else 
    echo "Let's stay boring"
fi

Le package de boîte de dialogue est installé par défaut au moins avec SUSE Linux.

8
Thorsten Staerk

J'ai remarqué que personne n'avait posté de réponse montrant un menu d'écho multiligne pour une entrée utilisateur aussi simple. Voici donc mon aperçu:

#!/bin/bash

function ask_user() {    

echo -e "
#~~~~~~~~~~~~#
| 1.) Yes    |
| 2.) No     |
| 3.) Quit   |
#~~~~~~~~~~~~#\n"

read -e -p "Select 1: " choice

if [ "$choice" == "1" ]; then

    do_something

Elif [ "$choice" == "2" ]; then

    do_something_else

Elif [ "$choice" == "3" ]; then

    clear && exit 0

else

    echo "Please select 1, 2, or 3." && sleep 3
    clear && ask_user

fi
}

ask_user

Cette méthode a été publiée dans l’espoir que quelqu'un puisse la trouver utile et gagner du temps.

6
Yokai

Version à choix multiple:

ask () {                        # $1=question $2=options
    # set REPLY
    # options: x=..|y=..
    while $(true); do
        printf '%s [%s] ' "$1" "$2"
        stty cbreak
        REPLY=$(dd if=/dev/tty bs=1 count=1 2> /dev/null)
        stty -cbreak
        test "$REPLY" != "$(printf '\n')" && printf '\n'
        (
            IFS='|'
            for o in $2; do
                if [ "$REPLY" = "${o%%=*}" ]; then
                    printf '\n'
                    break
                fi
            done
        ) | grep ^ > /dev/null && return
    done
}

Exemple:

$ ask 'continue?' 'y=yes|n=no|m=maybe'
continue? [y=yes|n=no|m=maybe] g
continue? [y=yes|n=no|m=maybe] k
continue? [y=yes|n=no|m=maybe] y
$

Il va régler REPLY sur y (dans le script).

4
Ernest A

Inspiré par les réponses de @Mark et @Myrddin, j'ai créé cette fonction pour une invite universelle.

uniprompt(){
    while true; do
        echo -e "$1\c"
        read opt
        array=($2)
        case "${array[@]}" in  *"$opt"*) eval "$3=$opt";return 0;; esac
        echo -e "$opt is not a correct value\n"
    done
}

utilisez-le comme ceci:

unipromtp "Select an option: (a)-Do one (x)->Do two (f)->Do three : " "a x f" selection
echo "$selection"
4
poxtron

plus générique serait:

function menu(){
    title="Question time"
    Prompt="Select:"
    options=("Yes" "No" "Maybe")
    echo "$title"
    PS3="$Prompt"
    select opt in "${options[@]}" "Quit/Cancel"; do
        case "$REPLY" in
            1 ) echo "You picked $opt which is option $REPLY";;
            2 ) echo "You picked $opt which is option $REPLY";;
            3 ) echo "You picked $opt which is option $REPLY";;
            $(( ${#options[@]}+1 )) ) clear; echo "Goodbye!"; exit;;
            *) echo "Invalid option. Try another one.";continue;;
         esac
     done
     return
}
4
Alexander Löfqvist

Une méthode simple consiste à utiliser xargs -p ou gnu parallel --interactive.

J'aime un peu mieux le comportement de xargs pour cela, car il exécute chaque commande immédiatement après l'invite comme d'autres commandes unix interactives, plutôt que de collecter les éléments à exécuter à la fin. (Vous pouvez Ctrl-C après avoir passé à travers ceux que vous vouliez.)

par exemple.,

echo *.xml | xargs -p -n 1 -J {} mv {} backup/
3
Joshua Goldberg

En tant qu'ami d'une commande d'une ligne, j'ai utilisé ce qui suit:

while [ -z $Prompt ]; do read -p "Continue (y/n)?" choice;case "$choice" in y|Y ) Prompt=true; break;; n|N ) exit 0;; esac; done; Prompt=;

Longform écrit, cela fonctionne comme ceci:

while [ -z $Prompt ];
  do read -p "Continue (y/n)?" choice;
  case "$choice" in
    y|Y ) Prompt=true; break;;
    n|N ) exit 0;;
  esac;
done;
Prompt=;
3
ccDict

J'ai utilisé la déclaration case à plusieurs reprises dans un tel scénario. L'utilisation de la déclaration de cas est un bon moyen de s'y prendre. Une boucle while, qui résume le bloc case, qui utilise une condition booléenne peut être mise en œuvre afin de permettre un contrôle encore plus poussé du programme et de répondre à de nombreuses autres exigences. Une fois que toutes les conditions sont remplies, vous pouvez utiliser une variable break qui transmettra le contrôle à la partie principale du programme. En outre, pour répondre à d'autres conditions, des instructions conditionnelles peuvent bien sûr être ajoutées pour accompagner les structures de contrôle: instruction case et possibilité de boucle while.

Exemple d'utilisation d'une instruction case pour répondre à votre demande

#! /bin/sh 

# For potential users of BSD, or other systems who do not
# have a bash binary located in /bin the script will be directed to
# a bourne-Shell, e.g. /bin/sh

# NOTE: It would seem best for handling user entry errors or
# exceptions, to put the decision required by the input 
# of the Prompt in a case statement (case control structure), 

echo Would you like us to perform the option: "(Y|N)"

read inPut

case $inPut in
    # echoing a command encapsulated by 
    # backticks (``) executes the command
    "Y") echo `Do something crazy`
    ;;
    # depending on the scenario, execute the other option
    # or leave as default
    "N") echo `execute another option`
    ;;
esac

exit
3
oOpSgEo

Je vous suggère tilisez le dialogue ...

Apprenti Linux: Améliorer les scripts du shell Bash en utilisant la boîte de dialogue

La commande dialog permet l'utilisation de fenêtres dans les scripts Shell afin de rendre leur utilisation plus interactive.

c'est simple et facile à utiliser, il y a aussi une version de gnome appelée gdialog qui prend exactement les mêmes paramètres, mais l'affiche dans un style graphique sur X.

3
Osama Al-Maadeed

En réponse aux autres:

Vous n'avez pas besoin de spécifier la casse dans BASH4, utilisez simplement le ',' pour faire une var minuscule. De plus, je n'aime pas trop mettre du code à l'intérieur du bloc de lecture, obtenir le résultat et le traiter en dehors du bloc de lecture IMO. Incluez également un "q" pour quitter l'OMI. Enfin, pourquoi taper "oui", utilisez simplement -n1 et demandez à la presse y.

Exemple: l'utilisateur peut appuyer sur y/n et sur q pour quitter.

ans=''
while true; do
    read -p "So is MikeQ the greatest or what (y/n/q) ?" -n1 ans
    case ${ans,,} in
        y|n|q) break;;
        *) echo "Answer y for yes / n for no  or q for quit.";;
    esac
done

echo -e "\nAnswer = $ans"

if [[ "${ans,,}" == "q" ]] ; then
        echo "OK Quitting, we will assume that he is"
        exit 0
fi

if [[ "${ans,,}" == "y" ]] ; then
        echo "MikeQ is the greatest!!"
else
        echo "No? MikeQ is not the greatest?"
fi
2
Mike Q

Oui/Non/Annuler

Une fonction

#!/usr/bin/env bash
@confirm() {
  local message="$*"
  local result=''

  echo -n "> $message (Yes/No/Cancel) " >&2

  while [ -z "$result" ] ; do
    read -s -n 1 choice
    case "$choice" in
      y|Y ) result='Y' ;;
      n|N ) result='N' ;;
      c|C ) result='C' ;;
    esac
  done

  echo $result
}

Usage

case $(@confirm 'Confirm?') in
  Y ) echo "Yes" ;;
  N ) echo "No" ;;
  C ) echo "Cancel" ;;
esac

Confirmer avec une entrée utilisateur propre

Une fonction

#!/usr/bin/env bash
@confirm() {
  local message="$*"
  local result=3

  echo -n "> $message (y/n) " >&2

  while [[ $result -gt 1 ]] ; do
    read -s -n 1 choice
    case "$choice" in
      y|Y ) result=0 ;;
      n|N ) result=1 ;;
    esac
  done

  return $result
}

Usage

if @confirm 'Confirm?' ; then
  echo "Yes"
else
  echo "No"
fi
2
Eduardo Cuomo
yn() {
  if [[ 'y' == `read -s -n 1 -p "[y/n]: " Y; echo $Y` ]];
  then eval $1;
  else eval $2;
  fi }
yn 'echo yes' 'echo no'
yn 'echo absent no function works too!'
2
jlettvin