มีฟังก์ชั่นเริ่มต้น / ยูทิลิตี้เพื่อแจ้งผู้ใช้ว่าใช่ / ไม่ใช่ในสคริปต์ 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
คุณสามารถลองใช้ a selectแต่อย่างอื่นฉันไม่เห็นวิธีที่ง่ายกว่า
muru

2
@muru ฉันขโมยความคิดของคุณโดยสิ้นเชิง ฉันหวังว่าฉันสามารถส่งตัวแทนของคุณกับคุณ
เกล็นแจ็คแมน

@glennjackman ฉันจะเรียกมันว่าการทำงานร่วมกัน ;)
muru

คำตอบ:


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
หากโปรแกรมโต้ตอบเป็นที่ยอมรับจะไม่dialogหรือwhiptailจะเหมาะมากที่จะ CLI?
muru

2
จริง เพิ่มไปยังคำตอบ
เกล็นแจ็คแมน

1
โดยส่วนตัวแล้วฉันชอบส้อม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

ด้วยselectคำแนะนำของ @ muru ฟังก์ชันสามารถกระชับได้มาก:

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

ฉันใช้สิ่งต่อไปนี้:

  • เริ่มต้นที่ไม่:
    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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.