ฉันจะพร้อมต์สำหรับอินพุตใช่ / ไม่ใช่ / ยกเลิกในสคริปต์เชลล์ Linux ได้อย่างไร


1443

ฉันต้องการหยุดการป้อนข้อมูลในเชลล์สคริปต์และแจ้งให้ผู้ใช้เลือกได้
มาตรฐานYes, NoหรือCancelคำถามประเภท
ฉันจะทำสิ่งนี้ให้สำเร็จได้ในพรอมต์ทุบตีทั่วไป


11
เช่นเดียวกับบันทึกย่อ: อนุสัญญาสำหรับข้อความแจ้งนั้นเป็นเช่นนั้นหากคุณแสดง[yn]ตัวเลือกตัวเลือกที่เป็นตัวพิมพ์ใหญ่นั้นจะเป็นค่าเริ่มต้นเช่น[Yn]ค่าเริ่มต้นคือ"ใช่" และ[yN]ค่าเริ่มต้นเป็น "ไม่" ดูux.stackexchange.com/a/40445/43532
Tyzoid

ทุกคนที่มาที่นี่จาก ZSH ดูคำตอบนี้สำหรับวิธีใช้readคำสั่งเพื่อแจ้งให้ทราบ
smac89

คำตอบ:


1617

วิธีที่ง่ายที่สุดและแพร่หลายที่สุดในการรับอินพุตของผู้ใช้ที่เชลล์พรอมต์คือreadคำสั่ง วิธีที่ดีที่สุดในการอธิบายการใช้งานคือการสาธิตอย่างง่าย:

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

อีกวิธีหนึ่ง, ชี้ให้เห็นโดยSteven Huwigเป็นทุบตีของselectคำสั่ง นี่คือตัวอย่างเดียวกันโดยใช้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

ด้วยselectคุณไม่จำเป็นต้องฆ่าเชื้ออินพุต - มันจะแสดงตัวเลือกที่มีอยู่และคุณพิมพ์หมายเลขที่สอดคล้องกับตัวเลือกของคุณ นอกจากนี้ยังวนwhile trueซ้ำโดยอัตโนมัติจึงไม่จำเป็นต้องวนซ้ำเพื่อลองอีกครั้งหากมีการป้อนข้อมูลที่ไม่ถูกต้อง

นอกจากนี้Léa Grisแสดงให้เห็นถึงวิธีการที่จะทำให้ไม่เชื่อเรื่องพระเจ้าภาษาคำขอในคำตอบของเธอ การปรับตัวอย่างแรกของฉันเพื่อให้บริการหลายภาษาได้ดีขึ้นอาจมีลักษณะเช่นนี้:

set -- $(locale LC_MESSAGES)
yesptrn="$1"; noptrn="$2"; yesword="$3"; noword="$4"

while true; do
    read -p "Install (${yesword} / ${noword})? " yn
    case $yn in
        ${yesptrn##^} ) make install; break;;
        ${noptrn##^} ) exit;;
        * ) echo "Answer ${yesword} / ${noword}.";;
    esac
done

เห็นได้ชัดว่าสตริงการสื่อสารอื่น ๆ ยังคงไม่ได้แปลที่นี่ (ติดตั้งตอบ) ซึ่งจะต้องได้รับการแก้ไขในการแปลที่สมบูรณ์มากขึ้น แต่แม้การแปลบางส่วนจะเป็นประโยชน์ในหลาย ๆ กรณี

สุดท้ายโปรดตรวจสอบคำตอบที่ดีเยี่ยมโดยเอฟ HAURI


30
การใช้ Bash ใน OS X Leopard ฉันเปลี่ยนexitเป็นbreakปิดไม่ให้แท็บเมื่อฉันเลือก 'ไม่'
แต้ม Piepmeier

1
สิ่งนี้ทำงานกับตัวเลือกได้นานกว่าใช่หรือไม่? ในกรณีข้อคุณเขียนสิ่งที่ชอบ: ติดตั้งโปรแกรมและไม่ทำอะไรหลังจากนั้น) ทำการติดตั้ง; หยุดพัก;
Shawn

1
@Shawn แน่นอนว่าคุณสามารถอ่านได้โดยใช้รูปแบบกลมหรือแบบ regex ที่สนับสนุนโดยคำสั่ง switch ของ bash shell มันตรงกับข้อความที่พิมพ์ลงในรูปแบบของคุณจนกว่าจะพบการแข่งขัน การใช้การเลือกรายการของตัวเลือกจะถูกกำหนดให้กับคำสั่งและมันจะแสดงให้กับผู้ใช้ คุณสามารถมีรายการในรายการยาวหรือสั้นตามที่คุณต้องการ ฉันแนะนำและตรวจสอบหน้า man ของพวกเขาสำหรับข้อมูลการใช้งานที่ครอบคลุม
Myrddin Emrys

3
ทำไมมีbreakในselectกรณีที่ไม่มีห่วง?
Jayen

1
@akostadinov ฉันควรอ่านประวัติการแก้ไขของฉันมากกว่านี้ คุณถูกต้องฉันผิดและฉันแนะนำข้อผิดพลาดตามคำแนะนำของ Jayan ใช่มั้ย ข้อผิดพลาดได้รับการแก้ไขในภายหลัง แต่การแก้ไขอยู่ห่างกันมากจนฉันจำไม่ได้ว่าเปลี่ยน
Myrddin Emrys

526

อย่างน้อยห้าคำตอบสำหรับคำถามทั่วไปหนึ่งข้อ

ขึ้นอยู่กับ

  • สอดคล้องกับ: สามารถทำงานกับระบบที่ไม่ดีด้วยทั่วไป สภาพแวดล้อม
  • เจาะจง: ใช้bashisms ที่เรียกว่า

และถ้าคุณต้องการ

  • ง่าย `` ในบรรทัด '' คำถาม / คำตอบ (การแก้ปัญหาทั่วไป)
  • อินเทอร์เฟซที่จัดรูปแบบสวยเช่น ขึ้นไปแบบกราฟิกโดยใช้ libgtk หรือ libqt ...
  • ใช้ความสามารถประวัติ readline ที่มีประสิทธิภาพ

1. POSIX โซลูชั่นทั่วไป

คุณสามารถใช้readคำสั่งตามด้วย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

(ขอบคุณความคิดเห็นของ Adam Katz : แทนที่การทดสอบข้างต้นด้วยแบบพกพาที่มากขึ้นและหลีกเลี่ยงหนึ่งส้อม :)

POSIX แต่เป็นคุณสมบัติปุ่มเดียว

แต่ถ้าคุณไม่ต้องการให้ผู้ใช้ตีReturnคุณสามารถเขียน:

( แก้ไข:ตามที่ @JonathanLeffler แนะนำอย่างถูกต้องการบันทึกการกำหนดค่าของ stty อาจดีกว่าเพียงแค่บังคับให้มีสติ )

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

หมายเหตุ:นี่คือการทดสอบภายใต้, , , และ !

เหมือนกัน แต่รออย่างชัดเจนสำหรับyหรือ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

ใช้เครื่องมือเฉพาะ

มีเครื่องมือมากมายที่ถูกสร้างขึ้นโดยใช้มีlibncurses, libgtk, libqtหรือไลบรารีกราฟิกอื่น ๆ ตัวอย่างเช่นการใช้whiptail:

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

คุณอาจต้องเปลี่ยนwhiptailเครื่องมืออื่นที่คล้ายกันขึ้นอยู่กับระบบของคุณ:

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

โดยที่20ความสูงของกล่องโต้ตอบเป็นจำนวนบรรทัดและ60ความกว้างของกล่องโต้ตอบ เครื่องมือเหล่านี้ทั้งหมดมีไวยากรณ์ใกล้เคียงกัน

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

2. Bash โซลูชั่นเฉพาะ

พื้นฐานในวิธีการสาย

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

ฉันชอบที่จะใช้caseดังนั้นฉันสามารถทดสอบได้yes | ja | si | ouiถ้าจำเป็น ...

สอดคล้องกับคุณสมบัติปุ่มเดียว

ภายใต้ bash เราสามารถระบุความยาวของอินพุตที่ต้องการสำหรับreadคำสั่ง:

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

ภายใต้ bash readคำสั่งยอมรับพารามิเตอร์การหมดเวลาซึ่งอาจเป็นประโยชน์

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

3. เทคนิคบางอย่างสำหรับเครื่องมือเฉพาะ

กล่องโต้ตอบที่ซับซ้อนมากขึ้นนอกเหนือจากyes - noจุดประสงค์ง่ายๆ

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

แถบความคืบหน้า:

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
) 

ตัวอย่างเล็ก ๆ น้อย ๆ :

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

ตัวอย่างเพิ่มเติม? ดูที่การใช้ whiptail สำหรับการเลือกอุปกรณ์USBและตัวเลือกที่เก็บข้อมูล USB ถอดได้: USBKeyChooser

5. การใช้ประวัติของ readline

ตัวอย่าง:

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

นี้จะสร้างไฟล์.myscript.historyของคุณใน$HOMEไดเรกทอรีกว่าที่คุณสามารถใช้คำสั่งประวัติศาสตร์ ReadLine เหมือนUp, Down, Ctrl+ rและอื่น ๆ


4
โปรดทราบว่าsttyมีตัวเลือกสำหรับการใช้งาน:-g นี้จะเรียกคืนการตั้งค่าตรงตามที่พวกเขาได้พบซึ่งอาจจะหรืออาจจะไม่เป็นเช่นเดียวกับold_stty=$(stty -g); stty raw -echo; …; stty "$old_stty" stty -sane
Jonathan Leffler

3
read answerจะตีความแบ็กสแลชก่อนการเว้นวรรคและการป้อนบรรทัด ใช้read -r answerแทนเป็นต่อSC2162
vlfig

1
วิธีการ "ใช้ประวัติของ readline" นั้นไม่เหมาะสมอย่างยิ่งสำหรับคำถามของ OP ฉันดีใจที่คุณรวมมันต่อไป ฉันมีสคริปต์ที่ซับซ้อนมากขึ้นมากมายที่ฉันตั้งใจจะอัปเดตด้วยรูปแบบนั้น
Bruno Bronosky

5
คุณสามารถใช้caseสำหรับ POSIX เช่นเดียวกับทุบตี (ใช้สัญลักษณ์แทนสภาพมากกว่าย่อยทุบตี: case $answer in; [Yy]* ) echo Yes ;;) แต่ฉันชอบใช้คำสั่งเงื่อนไขแทนความนิยมมากกว่าของคุณ[ "$answer" != "${answer#[Yy]}" ] echo "$answer" | grep -iq ^yมันพกพาได้มากกว่า (greps ที่ไม่ใช่ของ GNU บางตัวทำงานไม่-qถูกต้อง) และไม่มีการเรียกระบบ ${answer#[Yy]}ใช้การขยายพารามิเตอร์เพื่อลบYหรือออกyจากจุดเริ่มต้น$answerทำให้เกิดความไม่เท่าเทียมกันเมื่อมีอยู่ ใช้งานได้ในเปลือก POSIX ใด ๆ (เส้นประ, ksh, bash, zsh, busybox ฯลฯ )
Adam Katz

1
@CarterPape ใช่นี่เป็นเรื่องตลก! แต่ในคำตอบที่ไม่ถูกต้องคุณอาจพบเคล็ดลับมากมาย (จุดที่สองนำเสนออย่างน้อย 3 วิธี)! และ ... จากประมาณ 5 ปีตอนนี้คุณเป็นคนแรกที่บอกวิธีการนับของฉัน! ;-))
F. Hauri

349
echo "Please enter some input: "
read input_variable
echo "You entered: $input_variable"

25
ฉันไม่เห็นด้วยเพราะใช้เพียงบางส่วนของฟังก์ชันการทำงานของกล่องโต้ตอบ 'ใช่ไม่ยกเลิก' ใน DOS ส่วนที่ไม่สามารถใช้งานได้คือการตรวจสอบอินพุต ... วนซ้ำจนกว่าจะได้รับคำตอบที่ถูกต้อง
Myrddin Emrys

1
(ชื่อเดิมคือคำถาม "ฉันพรอมต์สำหรับการป้อนข้อมูลในสคริปต์เปลือก Linux?")
pistos

8
แต่คำอธิบายคำถามดั้งเดิมจะไม่เปลี่ยนแปลงและจะขอให้ตอบกลับพร้อมท์ใช่ / ไม่ใช่ / ยกเลิก ชื่อได้รับการอัปเดตให้ชัดเจนกว่าชื่อเดิมของฉัน แต่คำอธิบายคำถามนั้นชัดเจนเสมอ (ตามความเห็นของฉัน)
Myrddin Emrys

165

คุณสามารถใช้คำสั่งอ่านในตัว; ใช้-pตัวเลือกนี้เพื่อถามคำถามผู้ใช้

ตั้งแต่ BASH4 คุณสามารถใช้-iเพื่อแนะนำคำตอบ:

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

(แต่อย่าลืมใช้ตัวเลือก "readline" -eเพื่ออนุญาตให้แก้ไขบรรทัดด้วยปุ่มลูกศร)

ถ้าคุณต้องการตรรกะ "ใช่ / ไม่ใช่" คุณสามารถทำสิ่งนี้:

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

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

6
ควรสังเกตว่าFILEPATHเป็นชื่อตัวแปรที่คุณเลือกและตั้งค่าด้วยคำตอบของพรอมต์คำสั่ง ดังนั้นหากคุณต้องเปิดใช้vlc "$FILEPATH"งานเช่นvlcจะเปิดไฟล์นั้น
Ken Sharp เมื่อ

ประโยชน์ที่ได้จาก-eตัวอย่างที่สอง (ง่ายคือใช่ / ไม่ใช่)
JBallin

เหตุผลใดที่จะใช้-e -pแทน-ep?
JBallin

1
หากไม่มีการ-eตั้งค่าสถานะ / ตัวเลือกคุณอาจ (ขึ้นอยู่กับการนำไปใช้) ไม่สามารถพิมพ์ "y" แล้วเปลี่ยนความคิดของคุณและแทนที่ด้วย "n" (หรือสิ่งอื่นสำหรับเรื่องนั้น); เมื่อจัดทำเอกสารคำสั่งรายการตัวเลือกแยกต่างหากจะดีกว่าสำหรับการอ่าน / ความชัดเจนท่ามกลางเหตุผลอื่น ๆ
yPhil

109

Bash ได้เลือกเพื่อจุดประสงค์นี้

select result in Yes No Cancel
do
    echo $result
done

18
+1 ทางออกที่ง่ายอย่างแท้จริง สิ่งเดียวที่: นี้จะแจ้งให้และ Promt และทัน ... จนกระทั่งคุณเพิ่มexitภายใน :)
Kaiser

5
(ไกเซอร์: หากต้องการแยกออกจากกันเพียงป้อน EOT: Ctrl-Dแต่แน่นอนว่ารหัสจริงที่ใช้จะต้องหยุดพักหรือออกจากร่างกาย)
Zorawar

12
สิ่งนี้จะไม่อนุญาตให้คุณป้อน y หรือ n แต่คุณเลือกได้โดยป้อน 1 2 หรือ 3
djjeck

3
exitจะออกจากสคริปต์ทั้งหมดเข้าด้วยกันbreakจะออกจากลูปที่คุณอยู่เท่านั้น (ถ้าคุณอยู่บน a whileหรือcaseลูป)
wranvaud


36

นี่คือสิ่งที่ฉันรวบรวม:

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

ฉันเป็นผู้เริ่มต้นดังนั้นเอาสิ่งนี้ด้วยเม็ดเกลือ แต่ดูเหมือนว่าจะใช้ได้


9
หากคุณเปลี่ยนcase $yn inเป็นcase ${yn:-$2} inคุณสามารถใช้อาร์กิวเมนต์ที่สองเป็นค่าเริ่มต้น Y หรือ N
jchook

1
หรือการเปลี่ยนแปลงcase $ynในการcase "${yn:-Y}"ที่จะมีใช่เป็นค่าเริ่มต้น
rubo77

35
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?"

...

1
ใส่ช่องว่างสี่ช่องในตอนต้นของแต่ละบรรทัดเพื่อคงรูปแบบของโค้ดไว้
Jouni K. Seppänen

10
เหตุใดเราจึงให้ 'y' และ 'n' เป็นพารามิเตอร์เพื่อสอบถาม () หากสวิตช์ตัวพิมพ์เล็กและใหญ่มีการเข้ารหัสหรือไม่ นั่นเป็นเพียงการขอทางที่ผิด เป็นพารามิเตอร์คงที่ไม่สามารถเปลี่ยนได้ดังนั้น echo ในบรรทัดที่ 2 ควรอ่าน: echo -n "$ 1 [Y / N]?" ไม่สามารถเปลี่ยนแปลงได้ดังนั้นจึงไม่ควรระบุ
Myrddin Emrys

1
@MyrddinEmrys คุณช่วยอธิบายความคิดเห็นของคุณได้ไหม? หรือโพสต์ลิงก์ไปยังบทความหรือคำหลักสองสามคำเพื่อให้ฉันสามารถค้นคว้าด้วยตัวเอง
Mateusz Piotrowski

4
@MateuszPiotrowski คำตอบนี้ได้รับการแก้ไขและปรับปรุงตั้งแต่ฉันแสดงความคิดเห็น คุณสามารถคลิกลิงก์ 'แก้ไข 23 ธันวาคม' ด้านบนเพื่อดูคำตอบที่ผ่านมาทั้งหมด ย้อนกลับไปในปี 2008 รหัสนั้นค่อนข้างแตกต่างกัน
Myrddin Emrys

27

คุณต้องการ:

  • คำสั่ง Bash builtin (เช่นพกพา)
  • ตรวจสอบ TTY
  • คำตอบเริ่มต้น
  • หมดเวลา
  • คำถามสี

เศษเล็กเศษน้อย

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

คำอธิบาย

  • [[ -t 0 ]] && read ...=> คำสั่งโทรreadถ้า TTY
  • read -n 1 => รอหนึ่งตัวอักษร
  • $'\e[1;32m ... \e[0m '=> พิมพ์เป็นสีเขียว
    (สีเขียวใช้ได้เพราะสามารถอ่านได้ทั้งบนพื้นหลังสีขาว / ดำ)
  • [[ $do_xxxx =~ ^(y|Y|)$ ]] => bash regex

การหมดเวลา => คำตอบเริ่มต้นคือไม่

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

26

วิธีที่ง่ายที่สุดในการบรรลุเป้าหมายด้วยจำนวนบรรทัดน้อยที่สุดมีดังนี้:

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

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

นี่ifเป็นเพียงตัวอย่าง: มันขึ้นอยู่กับคุณว่าจะจัดการกับตัวแปรนี้อย่างไร


20

ใช้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

แล้วทุกอย่างอื่นที่คุณต้องการ


17

วิธีการแก้ปัญหานี้อ่านตัวอักษรเดียวและเรียกใช้ฟังก์ชั่นในการตอบสนองใช่

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

2
@Jav เสียงก้องพิมพ์ขึ้นบรรทัดใหม่หลังจากการตอบสนองของคุณ หากไม่มีมันสิ่งต่อไปที่จะพิมพ์จะปรากฏขึ้นทันทีหลังจากที่คุณตอบกลับในบรรทัดเดียวกัน ลองลบเครื่องหมายechoเพื่อดูด้วยตัวคุณเอง
Dennis

13

ในการรับค่าอินพุตเหมือน ncurses ที่ดีให้ใช้กล่องโต้ตอบคำสั่งดังนี้:

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

แพ็คเกจการโต้ตอบถูกติดตั้งโดยค่าเริ่มต้นอย่างน้อยด้วย SUSE Linux ดูเหมือนกับ: คำสั่ง "dialog" ในการดำเนินการ


12
read -e -p "Enter your choice: " choice

-eตัวเลือกที่ช่วยให้ผู้ใช้แก้ไขการป้อนข้อมูลที่ใช้ปุ่มลูกศร

หากคุณต้องการใช้คำแนะนำเป็นอินพุต:

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

-i ตัวเลือกพิมพ์อินพุตที่มีการชี้นำ


เห่า-e -iจะไม่ได้ทำงานในการดวลจุดโทษ (บอร์นเปลือก) แต่คำถามคือทุบตีที่ติดแท็กโดยเฉพาะ ..
Jahid

12

คุณสามารถใช้ค่าเริ่มต้นREPLYใน a read, แปลงเป็นตัวพิมพ์เล็กและเปรียบเทียบกับชุดของตัวแปรที่มีนิพจน์
สคริปต์ยังสนับสนุน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

เป็นไปได้ที่จะจัดการกับโลแคล "Yes / No choice" ใน POSIX เชลล์ โดยใช้รายการของLC_MESSAGESหมวดหมู่โลแคลแม่มดจัดทำรูปแบบ RegEx สำเร็จรูปเพื่อจับคู่อินพุตและสตริงสำหรับใช่ไม่ใช่

#!/usr/bin/env sh

# Getting LC_MESSAGES values into variables
# shellcheck disable=SC2046 # Intended IFS splitting
IFS='
' set -- $(locale LC_MESSAGES)

yesexpr="$1"
noexpr="$2"
yesstr="$3"
nostr="$4"
messages_codeset="$5" # unused here, but kept as documentation

# Display Yes / No ? prompt into locale
echo "$yesstr / $nostr ?"

# Read answer
read -r yn

# Test answer
case "$yn" in
# match only work with the character class from the expression
  ${yesexpr##^}) echo "answer $yesstr" ;;
  ${noexpr##^}) echo "answer $nostr" ;;
esac

แก้ไข: ตามที่@Urhixidurพูดถึงในความคิดเห็นของเขา :

น่าเสียดายที่ POSIX ระบุเพียงสองรายการแรกเท่านั้น (ใช่แล้วและ noexpr) บน Ubuntu 16 yesstr และ nostr ว่างเปล่า

ดู: https://www.ee.ryerson.ca/~courses/ele709/susv4/xrat/V4_xbd_chap07.html#tag_21_07_03_06

LC_MESSAGES

yesstrและnostrคำหลักที่เกิดเหตุและYESSTRและNOSTRlanginfo รายการถูกก่อนนำมาใช้เพื่อตอบสนองผู้ใช้แข่งขันยืนยันและลบ ใน POSIX.1-2008 ที่yesexpr, noexpr, YESEXPRและNOEXPRขยายการแสดงออกปกติได้เข้ามาแทนที่พวกเขา แอปพลิเคชันควรใช้เครื่องมืออำนวยความสะดวกในการรับส่งข้อความทั่วไปตามตำแหน่งที่ตั้งเพื่อออกข้อความแจ้งเตือนซึ่งรวมถึงตัวอย่างคำตอบที่ต้องการ

อีกทางเลือกหนึ่งโดยใช้สถานที่ทาง Bash:

#!/usr/bin/env bash

IFS=$'\n' read -r -d '' yesexpr noexpr _ < <(locale LC_MESSAGES)

printf -v yes_or_no_regex "(%s)|(%s)" "$yesexpr" "$noexpr"

printf -v prompt $"Please answer Yes (%s) or No (%s): " "$yesexpr" "$noexpr"

declare -- answer=;

until [[ "$answer" =~ $yes_or_no_regex ]]; do
  read -rp "$prompt" answer
done

if [[ -n "${BASH_REMATCH[1]}" ]]; then
  echo $"You answered: Yes"
else
  echo $"No, was your answer."
fi

คำตอบนั้นถูกจับคู่โดยใช้ regexps ที่จัดไว้ให้ของสภาพแวดล้อม

หากต้องการแปลข้อความที่เหลือให้ใช้bash --dump-po-strings scriptnameเพื่อส่งออกสตริง po สำหรับการแปลภาษาท้องถิ่น:

#: scriptname:8
msgid "Please answer Yes (%s) or No (%s): "
msgstr ""
#: scriptname:17
msgid "You answered: Yes"
msgstr ""
#: scriptname:19
msgid "No, was your answer."
msgstr ""

ฉันชอบการเพิ่มตัวเลือกภาษาที่ไม่เชื่อเรื่องพระเจ้า ทำได้ดี.
Myrddin Emrys

1
น่าเสียดายที่ POSIX จะระบุเฉพาะสองรายการแรกเท่านั้น (yesexpr และ noexpr) บน Ubuntu 16 yesstr และ nostr ว่างเปล่า
Urhixidur

1
แต่เดี๋ยวก่อน! มีข่าวที่เลวร้ายกว่า! นิพจน์คำสั่ง bash case ไม่ปกติพวกเขาเป็นนิพจน์ชื่อไฟล์ ดังนั้น yesexpr และ noexpr ของ Ubuntu 16 ("^ [yY]. *" และ "^ [nN]. *" ตามลำดับ) จะล้มเหลวอย่างสิ้นเชิงเนื่องจากช่วงเวลาที่ฝังตัว ในนิพจน์ทั่วไป ". *" หมายถึง "อักขระที่ไม่ใช่บรรทัดใหม่ใด ๆ ศูนย์หรือมากกว่านั้น" แต่ในกรณีคำสั่งมันเป็นตัวอักษร "." ตามด้วยจำนวนอักขระใด ๆ
Urhixidur

1
ในที่สุดสิ่งที่ดีที่สุดที่สามารถทำได้ด้วยyesexprและnoexprในสภาพแวดล้อมของเชลล์ใช้ในการจับคู่ RegEx เฉพาะของ Bashif [[ "$yn" =~ $yesexpr ]]; then echo $"Answered yes"; else echo $"Answered no"; fi
Léa Gris

10

กดปุ่มเดียวเท่านั้น

ต่อไปนี้เป็นวิธีการที่ยาวกว่า แต่ใช้ซ้ำได้และแบบแยกส่วน

  • ส่งคืน0= ใช่และ1= ไม่
  • ไม่จำเป็นต้องกด Enter - เพียงตัวเดียว
  • สามารถกดenterเพื่อยอมรับตัวเลือกเริ่มต้น
  • สามารถปิดการใช้งานตัวเลือกเริ่มต้นเพื่อบังคับให้เลือก
  • ผลงานของทั้งสองและzshbash

เริ่มต้นที่ "ไม่" เมื่อกด Enter

โปรดทราบว่าNเป็นตัวพิมพ์ใหญ่ กดที่นี่เพื่อกดยอมรับค่าเริ่มต้น:

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

และโปรดทราบว่า[y/N]?จะมีการต่อท้ายโดยอัตโนมัติ ยอมรับค่าเริ่มต้น "ไม่" ดังนั้นจึงไม่มีสิ่งใดสะท้อนกลับ

แจ้งอีกครั้งจนกว่าจะได้รับการตอบสนองที่ถูกต้อง:

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

เริ่มต้นที่ "ใช่" เมื่อกด Enter

โปรดทราบว่าYเป็นตัวพิมพ์ใหญ่:

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

ด้านบนฉันเพิ่งกด Enter ดังนั้นคำสั่งจึงรัน

ไม่มีการตั้งค่าเริ่มต้นenter- ต้องการyหรือ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

ที่นี่1หรือเท็จถูกส่งกลับ โปรดทราบว่าด้วยฟังก์ชั่นระดับต่ำกว่านี้คุณจะต้องให้[y/n]?พรอมต์ของคุณเอง

รหัส

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

เมื่อผมทดสอบสคริปต์นี้แทน outut ข้างต้นผมได้, Show dangerous command [y/N]? [y/n]?และShow dangerous command [Y/n]? [y/n]?
Ilias Karim

ขอบคุณ @IliasKarim ฉันได้แก้ไขแล้วในตอนนี้
Tom Hale

9

ขออภัยที่โพสต์ข้อความเก่า ๆ เมื่อหลายสัปดาห์ก่อนฉันพบปัญหาที่คล้ายกันในกรณีของฉันฉันต้องการโซลูชันที่ใช้งานได้กับโปรแกรมติดตั้งออนไลน์เช่น:curl -Ss https://raw.github.com/_____/installer.sh | bash

ใช้read yesno < /dev/ttyงานได้ดีสำหรับฉัน:

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

หวังว่านี่จะช่วยใครซักคน


ส่วนที่สำคัญคือการตรวจสอบอินพุต ฉันคิดว่าการปรับตัวอย่างแรกของฉันให้ยอมรับttyอินพุตเช่นเดียวกับคุณและสำหรับการป้อนข้อมูลที่ไม่ดี (ลองจินตนาการถึงอักขระสองสามตัวในบัฟเฟอร์วิธีการของคุณจะบังคับให้ผู้ใช้เลือกไม่เสมอ )
Myrddin Emrys

7

ฉันสังเกตเห็นว่าไม่มีใครโพสต์คำตอบที่แสดงเมนู echo หลายบรรทัดสำหรับการป้อนข้อมูลผู้ใช้อย่างง่ายดังนั้นนี่คือสิ่งที่ฉันทำได้:

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

วิธีนี้ถูกโพสต์ด้วยความหวังว่าบางคนอาจพบว่ามีประโยชน์และประหยัดเวลา


4

รุ่นหลายตัวเลือก:

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
}

ตัวอย่าง:

$ 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
$

มันจะตั้งค่าREPLYเป็นy(ภายในสคริปต์)


4

ฉันแนะนำให้คุณใช้กล่องโต้ตอบ ...

Linux Apprentice: ปรับปรุง Bash Shell Script โดยใช้ Dialog

คำสั่งการโต้ตอบช่วยให้การใช้กล่องหน้าต่างในเชลล์สคริปต์เพื่อให้การใช้งานโต้ตอบมากขึ้น

มันง่ายและใช้งานง่ายนอกจากนี้ยังมี gnome รุ่นที่เรียกว่า gdialog ซึ่งใช้พารามิเตอร์เดียวกัน แต่แสดงสไตล์ GUI บน X


สำหรับผู้อ่านทั่วไปลองดูตัวอย่างโดยใช้คำสั่งไดอะล็อกที่นี่: stackoverflow.com/a/22893526/363573
Stephan

4

แรงบันดาลใจจากคำตอบของ @Mark และ @Myrddin ฉันสร้างฟังก์ชั่นนี้ขึ้นมาเพื่อให้เป็นสากล

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
}

ใช้มันแบบนี้:

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

4

ทั่วไปมากขึ้นจะเป็น:

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
}

3

วิธีการหนึ่งที่ง่ายที่จะทำนี้จะมีxargs -pหรือ parallel --interactiveGNU

ฉันชอบพฤติกรรมของ xargs ที่ดีขึ้นเล็กน้อยเพราะมันดำเนินการแต่ละคำสั่งทันทีหลังจากพรอมต์เช่นคำสั่ง unix เชิงโต้ตอบอื่น ๆ แทนที่จะรวบรวม yesses ให้ทำงานในตอนท้าย (คุณสามารถ Ctrl-C หลังจากผ่านสิ่งที่คุณต้องการ)

เช่น,

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

ไม่เลว แต่xargs --interactiveจำกัด อยู่ที่ใช่หรือไม่ ตราบใดที่คุณต้องการนั่นก็เพียงพอแล้ว แต่คำถามเดิมของฉันให้ตัวอย่างกับผลลัพธ์ที่เป็นไปได้สามแบบ ฉันชอบที่มันสามารถสตรีมได้ สถานการณ์ทั่วไปจำนวนมากจะได้รับประโยชน์จากความสามารถในการทำ piped
Myrddin Emrys

ฉันเห็น. ความคิดของฉันคือว่า "ยกเลิก" หมายถึงเพียงแค่หยุดการดำเนินการทั้งหมดซึ่งสนับสนุนผ่าน Ctrl-C แต่ถ้าคุณต้องการทำสิ่งที่ซับซ้อนมากขึ้นในการยกเลิก (หรือไม่) สิ่งนี้จะไม่เพียงพอ
Joshua Goldberg

3

ในฐานะเพื่อนของคำสั่งหนึ่งบรรทัดฉันใช้สิ่งต่อไปนี้:

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 ที่เขียนใช้งานได้เช่นนี้:

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=;

คุณช่วยอธิบายการใช้ตัวแปรพร้อมท์ได้หรือไม่? ดูเหมือนว่าฉันจะถูกเช็ดหลังจากซับเดียวดังนั้นคุณจะใช้บรรทัดทำอะไรได้บ้าง?
Myrddin Emrys

พรอมต์จะถูกลบหลังจากห่วงในขณะที่ เพราะฉันต้องการตัวแปรพร้อมท์ให้เริ่มต้นหลังจากนั้น (เนื่องจากฉันใช้คำสั่งบ่อยขึ้น) การมีบรรทัดนี้ในเชลล์สคริปต์จะดำเนินการต่อเมื่อ y | Y ถูกพิมพ์และออกหาก n | N ถูกพิมพ์หรือทำซ้ำเพื่อขออินพุตสำหรับทุกอย่างอื่น
ccDict

3

ฉันเคยใช้caseคำสั่งสองสามครั้งในสถานการณ์เช่นนี้การใช้กรณีศึกษาเป็นวิธีที่ดีในการพิจารณา การwhileวนรอบที่รวมการcaseบล็อกซึ่งใช้เงื่อนไขบูลีนสามารถนำมาใช้เพื่อควบคุมโปรแกรมได้มากขึ้นและตอบสนองความต้องการอื่น ๆ อีกมากมาย หลังจากตรงตามเงื่อนไขทั้งหมดแล้วbreakสามารถใช้a ซึ่งจะผ่านการควบคุมกลับไปยังส่วนหลักของโปรแกรม นอกจากนี้เพื่อให้เป็นไปตามเงื่อนไขอื่น ๆ สามารถเพิ่มคำสั่งแบบมีเงื่อนไขของหลักสูตรเข้ากับโครงสร้างการควบคุม: caseคำสั่งและwhileลูปที่เป็นไปได้

ตัวอย่างการใช้caseคำสั่งเพื่อตอบสนองคำขอของคุณ

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

ใช่ / ไม่ใช่ / ยกเลิก

ฟังก์ชัน

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

การใช้

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

ยืนยันด้วยการป้อนข้อมูลผู้ใช้ที่สะอาด

ฟังก์ชัน

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

การใช้

if @confirm 'Confirm?' ; then
  echo "Yes"
else
  echo "No"
fi

2
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!'

ดูเหมือนว่าจะซับซ้อนและบอบบาง วิธีการเพียงแค่yn(){ read -s -n 1 -p '[y/n]'; test "$REPLY" = "y" ; } yn && echo success || echo failure
tripleee

2

ในการตอบสนองต่อผู้อื่น:

คุณไม่จำเป็นต้องระบุตัวพิมพ์ใน BASH4 เพียงใช้ ',,' เพื่อสร้างตัวพิมพ์เล็ก นอกจากนี้ฉันไม่ชอบวางโค้ดในบล็อกการอ่านรับผลลัพธ์และจัดการกับมันนอก IMO บล็อกการอ่าน รวมถึง 'q' เพื่อออกจาก IMO สุดท้ายทำไมพิมพ์ 'ใช่' เพียงแค่ใช้ -n1 และกด y

ตัวอย่าง: ผู้ใช้สามารถกด y / n และ q เพื่อเพิ่งออก

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

0

เวลาส่วนใหญ่ในสถานการณ์ดังกล่าวคุณต้องดำเนินการสคริปต์จนกว่าผู้ใช้จะป้อน "ใช่" และจะต้องหยุดเมื่อผู้ใช้เข้าสู่ "ไม่" ตัวอย่างด้านล่างจะช่วยให้คุณประสบความสำเร็จ!

#!/bin/bash
input="yes"
while [ "$input" == "yes" ]
do
  echo "execute script functionality here..!!"
  echo "Do you want to continue (yes/no)?"
  read input
done
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.