Existe-t-il une fonction / un utilitaire par défaut pour inviter l'utilisateur à répondre oui / non dans un script Bash?


14

Parfois, je dois demander à l'utilisateur oui / non pour confirmer quelque chose.

Habituellement, j'utilise quelque chose comme ça:

# Yes/no dialog. The first argument is the message that the user will see.
# If the user enters n/N, send exit 1.
check_yes_no(){
    while true; do
        read -p "$1" yn
        if [ "$yn" = "" ]; then
            yn='Y'
        fi
        case "$yn" in
            [Yy] )
                break;;
            [Nn] )
                echo "Aborting..."
                exit 1;;
            * )
                echo "Please answer y or n for yes or no.";;
        esac
    done;
}

Y a-t-il une meilleure façon de le faire? Cet utilitaire est peut-être déjà dans mon /bindossier?


2
Vous pouvez essayer d'utiliser un select, mais sinon je ne vois pas de manière plus simple.
muru

2
@muru, je vole totalement vos idées. J'aimerais pouvoir vous remettre mon représentant.
glenn jackman

@glennjackman Je l'appellerais collaboration. ;)
muru

Réponses:


13

Ah, il y a quelque chose de intégré: zenityest un programme de dialogue graphique:

if zenity --question --text="Is this OK?" --ok-label=Yes --cancel-label=No
then
    # user clicked "Yes"
else
    # user clicked "No"
fi

De plus zenity, vous pouvez utiliser l'un des éléments suivants:

if dialog --yesno "Is this OK?" 0 0; then ...
if whiptail --yesno "Is this OK?" 0 0; then ...

3
Si les programmes de dialogue sont acceptables, ne conviendraient-ils pas dialogou ne seraient-ils pas whiptailplus adaptés à CLI?
muru

2
En effet. Ajouté à la réponse.
glenn jackman

1
Personnellement, je préfère le fork, yadqui a plus d'améliorations et moins de bugs IMO.
Sparhawk

11

Cela me semble bien. Je ferais juste un peu moins "faire ou mourir":

  • si "Y" alors return 0
  • si "N" alors return 1

De cette façon, vous pouvez faire quelque chose comme:

if check_yes_no "Do important stuff? [Y/n] "; then
    # do the important stuff
else
    # do something else
fi
# continue with the rest of your script

Avec la selectsuggestion de @ muru , la fonction peut être très concise:

check_yes_no () { 
    echo "$1"
    local ans PS3="> "
    select ans in Yes No; do 
        [[ $ans == Yes ]] && return 0
        [[ $ans == No ]] && return 1
    done
}

1

En conclusion, j'ai écrit ce script :

#!/bin/bash

usage() { 
    echo "Show yes/no dialog, returns 0 or 1 depending on user answer"
    echo "Usage: $0 [OPTIONS]
    -x      force to use GUI dialog
    -m <string> message that user will see" 1>&2
    exit 1;
}

while getopts m:xh opts; do
    case ${opts} in
        x) FORCE_GUI=true;
            ;;
        m) MSG=${OPTARG}
            ;;
        h) usage
            ;;
    esac
done

if [ -z "$MSG" ];then
    usage
fi

# Yes/no dialog.
# If the user enters n/N, return 1.
while true; do
    if [ -z $FORCE_GUI ]; then
        read -p "$MSG" yn
        case "$yn" in
            [Yy] )
                exit 0;;
            [Nn] )
                echo "Aborting..." >&1
                exit 1;;
            * )
                echo "Please answer y or n for yes or no.";;
        esac
    else
        if [ -z $DISPLAY ]; then echo "DISPLAY variable is not set" >&1 ; exit 1; fi
        if zenity --question --text="$MSG" --ok-label=Yes --cancel-label=No; then
            exit 0
        else
            echo "Aborting..." >&1
            exit 1
        fi
    fi
done;

La dernière version du script peut être trouvée ici . Remplissez gratuitement pour modifier / modifier


0

J'utilise les éléments suivants:

  • par défaut à non:
    read -p "??? Are You sure [y/N]? " -n 1
    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
        echo "!!! Canceled by user."
        exit 1
    fi
  • par défaut à oui:
    read -p "??? Are You sure [Y/n]" -n 1
    if [[ $REPLY =~ ^[Nn]$ ]]; then
        echo "!!! Canceled by user."
        exit 1
    fi

0
 read -p 'Are you sure you want to continue? (y/n) ' -n 1 confirmation
 echo ''                                                                                                   
 if [[ $confirmation != 'y' && $confirmation != 'Y' ]]; then                                               
   exit 3                                                                                                
 fi
 # Code to execute if user wants to continue here.
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.