วิธีที่ดีกว่าในการยอมรับรูปแบบของ 'ใช่' จากเชลล์พรอมต์


27

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

แน่นอนว่าต้องมีวิธีที่ดีกว่าที่ฉันคิดไว้ ของคุณคืออะไรอ่านและรูปแบบสั้นใช้เวลากับเรื่องนี้?

read -p 'Answer this question with yes: ' answer
if [ "$answer" = 'Y'
  -o "$answer" = 'YES'
  -o "$answer" = 'Yes'
  -o "$answer" = 'y'
  -o "$answer" = 'yes'
  -o some-alternate-condition ]; then

  echo 'Surely this can be written better?'
fi

2
โหวตให้ปิด ในขณะที่ฉันสนใจคำถามนี้อาจเป็นคำถามเกี่ยวกับการเขียนโปรแกรมมากกว่าดังนั้นควรใช้ SO
phunehehe

การเขียนโปรแกรมคำตอบอาจจะเป็นสิ่งที่ชอบทุบตี: ตรวจสอบว่าองค์ประกอบอาร์เรย์มีอยู่
phunehehe

3
@phunehehe: ฉันไม่เห็นด้วยกับการย้ายไปที่ SO ไม่เพียงเพราะเรามีประวัติของการยอมรับการเขียนโปรแกรมเชลล์ แต่ยังเพราะมันไม่ได้เป็นเพียงคำถามว่าจะทำยังไง
Gilles 'หยุดความชั่วร้าย' ใน

4
ฉันเขียนสคริปต์แบบนั้นมาก จากนั้นโปรแกรมจะถูกแปลเป็นภาษาฝรั่งเศสและภาษาจีนตัวย่อ ฉันอ่านเวอร์ชั่นภาษาฝรั่งเศสและอ่านพรอมต์ของฉันถูกแปลเป็น "Enter oui or non" แต่แน่นอนว่ารหัสยังคงต้องการ "Y *" หรือ "N *"
Ben Jackson

คำตอบ:


15

การใช้ a caseค่อนข้างเท่ากัน แต่ไม่สมบูรณ์แบบเนื่องจากYEยอมรับว่าข้อความชอบ

read -p 'Answer this question with yes: ' answer
case "${answer}" in
    [yY]|[yY][eE][sS])
        echo 'Surely this can be written better?' ;;
esac

3
ฉันจะบอกว่าเจตนาของผู้ใช้ค่อนข้างชัดเจนจาก 'เจ้า'
Aeyoun

48

มาตรฐาน UNIX จัดเตรียมโค้ดตัวอย่างสำหรับสิ่งนี้โดยใช้localeยูทิลิตี้ :

if printf "%s\n" "$response" | grep -Eq "$(locale yesexpr)"
then
    affirmative processing goes here
else
    non-affirmative processing goes here
fi

คุ้มค่าสำหรับ 'yesexpr ในที่POSIXสถานที่ (และภาษาอังกฤษสถานที่เกิดในระบบจริง) "^[yY]"คือ มันจะถูกตีความว่าเป็นนิพจน์ปกติที่ขยาย ดูเพิ่มเติมที่ noexpr


1
ดี แต่ฉันดูเหมือนจะเป็นคนงี่เง่า ฉันจะหารายการข้อโต้แย้งที่localeรู้ได้จากที่ไหน หน้าคนในกล่อง Mac OS 10.5 ของฉันดูเหมือนจะไม่มี
dmckee

ดี คุณช่วยลิงค์กลับไปที่แหล่งที่มาได้ไหม
Aeyoun

3
@dmckee คุณสามารถทำได้locale -k LC_MESSAGES(และสำหรับ LC_whwh อื่น ๆ ) หรือดูที่นี่สำหรับรายการที่กำหนดโดยมาตรฐาน @Daniel มีแหล่งอื่นใดนอกเหนือจากหน้ายูทิลิตี้ของสถานที่ซึ่งฉันได้ทำการเชื่อมโยง
Random832

1
คำตอบที่ดีควรเป็นคำตอบที่ดี
jlliagre

6

อยู่ในทุบตี (หรือเปลือกอื่น ๆ หากคุณแสดงพรอมต์ที่เป็นอิสระ):

case $answer in
  [Yy]*) echo Ok;;
  *) echo "Can't you read? I said to say yes.";;
esac

นี้ยอมรับการตอบสนองเช่นynเป็นใช่ y(มีพื้นที่เริ่มต้น) เป็นไม่มีและwlkjzuhfodไม่มีซึ่งอาจจะไม่ดีที่สุด แต่มีความสอดคล้องกับแจ้งเปลือกทั่วไป: ว่าเป็นวิธีที่rm -i, find -okและอื่น ๆ ที่จะทำมัน

สิ่งนี้แสดงให้เห็นถึงปัญหาทั้งหมดของความเป็นสากล: ในภาษาอื่นคุณจะต้องแปลคำตอบที่คาดหวัง ไม่มีวิธีเชลล์มาตรฐานแล้ว คุณสามารถเปลี่ยนเป็นไดอะล็อกได้ แต่จากนั้นสคริปต์ของคุณจะต้องทำการติดตั้ง (มีอยู่ในหลายดิสทริบิวชัน แต่ไม่ได้ติดตั้งตามค่าเริ่มต้น)

if dialog --yesno "Choose yes" 0 0; then 

3

ฉันมักจะใช้ฟังก์ชั่นที่เรียบง่าย:

Confirm() { read -sn 1 -p "$* [Y/N]? "; [[ ${REPLY:0:1} = [Yy] ]]; }

ฟังก์ชั่นเพียงแค่ส่งกลับ0ถ้าYหรือyถูกป้อนและ1หากมีสิ่งอื่นเข้ามา มันสามารถใช้กับif...fi:

if Confirm "Type y or n"; then
echo "You typed y"
else
echo "You typed n"
fi

หรือเช่นนี้

Confirm "Type y" && echo "You typed y"

ถอด-sเพื่อให้มีประวัติภาพของสิ่งที่พิมพ์
Tom Hale

0

เพียงแก้ไข @faif ans อีกครั้ง

YesOrNo() {
        while :
        do
                read -p 'Do you want to Continue (yes/no?): ' answer
                case "${answer}" in
                    [yY]|[yY][eE][sS]) exit 0 ;;
                        [nN]|[nN][oO]) exit 1 ;;
                esac
        done
}


if $( YesOrNo ); then
        echo "Ans is yes.. Do something....."
else
        echo "Ans is No... skip.."
fi

ทดสอบ

root@ubuntu:~# bash confirm.sh
Do you want to Continue (yes/no?):  # if Blank Enter then ask again
Do you want to Continue (yes/no?):
Do you want to Continue (yes/no?):
Do you want to Continue (yes/no?): no
Ans is No... skip..
root@ubuntu:~# bash confirm.sh
Do you want to Continue (yes/no?):
Do you want to Continue (yes/no?):
Do you want to Continue (yes/no?): ye
Do you want to Continue (yes/no?): yes
Ans is yes.. Do something.....
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.