是否有任何默认功能/实用程序在Bash脚本中提示用户输入是/否?


14

有时我需要问用户是/否来确认某些内容。

通常我使用这样的东西:

# 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;
}

有更好的方法吗?该实用程序可能已经在我的/bin文件夹中了吗?


2
您可以尝试使用select,但否则我看不到更简单的方法。
muru

2
@muru,我完全是在偷你的想法。我希望我的代表可以交给你。
glenn jackman 2014年

@glennjackman我称之为协作。;)
muru 2014年

Answers:


13

啊,内置了一些东西:zenity一个图形对话框程序:

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

除了zenity,您还可以使用以下之一:

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

3
如果对话框程序是可以接受的,不会dialogwhiptail更适合CLI?
muru 2014年

2
确实。添加到答案。
glenn jackman 2014年

1
就个人而言,我更喜欢fork,yad它具有更多的改进和更少的IMO错误。
Sparhawk

11

对我来说很好。我只是减少它的“执行或死亡”:

  • 如果是“ Y” return 0
  • 如果“ N” return 1

这样,您可以执行以下操作:

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

根据@muru的select建议,该函数可能非常简洁:

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

1

作为结论,我写了这个脚本

#!/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;

最新版本的脚本可以在这里找到。免费填写以进行更改/编辑


0

我正在使用以下内容:

  • 默认为no:
    read -p "??? Are You sure [y/N]? " -n 1
    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
        echo "!!! Canceled by user."
        exit 1
    fi
  • 默认为是:
    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.
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.