ใช้คำสั่ง `select 'เพื่อพิมพ์เมนูใน Bash


10

ฉันพยายามใช้เมนูอย่างง่ายโดยใช้selectคำสั่ง สคริปต์ (สำหรับจุดประสงค์ในการทดสอบ) มีดังนี้:

#!/bin/bash
echo "*******************"
PS3='Select an option and press Enter: '
options=("apache" "named" "sendmail")
select opt in "${options[@]}"
do
  case $opt in
        "apache")
          date
          ;;
        "named")
          echo "test"
          ;;
        "sendmail")
          echo "test 2"
          ;;
        *) echo "invalid option";;
  esac
done
echo "*********************"

สคริปต์ไม่รู้จักอินพุตที่ถูกต้องที่ฉันให้และพิมพ์ข้อความ "ตัวเลือกที่ไม่ถูกต้อง" เสมอ เกิดอะไรขึ้นในสคริปต์นี้


4
ข้อมูลที่คุณป้อนคือ 1, 2 หรือ 3 ใช่ไหม
enzotib

คำตอบ:


11

เมนูของคุณที่แสดงโดยเลือกจะมีลักษณะดังนี้:

1) apache
2) named
3) sendmail
Select an option and press Enter: 

ในขณะนี้คุณป้อน "1" หรือ "2" หรือ "3": คุณไม่พิมพ์คำนั้น

และselectจะวนซ้ำจนกว่าจะเห็นbreakคำสั่งดังนั้นคุณต้องการสิ่งนี้:

  case $opt in
        "apache")
          date
          break
          ;;
        "named")
          echo "test"
          break
          ;;
        "sendmail")
          echo "test 2"
          break
          ;;
        *) echo "invalid option";;
  esac

หากคุณต้องการอนุญาตให้ผู้ใช้ป้อนหมายเลขหรือคำคุณสามารถเขียนสิ่งนี้:

select opt in "${options[@]}"; do
  case "$opt,$REPLY" in
    apache,*|*,apache)     do_something; break ;;
    named,*|*,named)       do_something; break ;;
    sendmail,*|*,sendmail) do_something; break ;;
  esac
done

เครื่องหมายจุลภาคไม่มีความสำคัญทางไวยากรณ์เพียงเพื่อให้สามารถจับคู่รูปแบบกับตัวแปร $ REPLY (ซึ่งเป็นสิ่งที่ผู้ใช้พิมพ์จริง) หรือตัวแปร $ opt


selectคำสั่งความต้องการไม่ได้break case
เกล็นแจ็คแมน

ขอบคุณ! ฉันไม่ได้ตระหนักว่ามันเป็นตัวเลือกที่เป็นตัวเลข duhh!
Sumod

ฮ่าฮ่าฉันเขียนโปรแกรมด้วยเช่นกันและคุณจำเป็นต้องbreakมีมันในทุกส่วน แต่คุณจะไม่จำเป็นต้องใช้breakในกรณี ... esacบล็อกในเชลล์สคริปต์ มันสามารถเกิดขึ้นได้อย่างง่ายดายเพื่อให้พวกเขาสับสน :-)
syntaxerror

1
@syntaxerror, คุณขวาคุณไม่จำเป็นต้องสำหรับbreak caseอย่างไรก็ตามคุณต้อง a breakเพื่อหลบหนีการselectวนซ้ำ
เกล็นแจ็คแมน

@glenn jackman ฉันต้องการให้สิ่งนี้กลายเป็นความคิดเห็นที่เป็นประโยชน์มากขึ้น (ดูต่อไป) ดังนั้นจะเป็นการดีถ้าคุณตกลงที่จะลบความคิดเห็นของคุณตั้งแต่ 12:55 ฉันจะทำเช่นเดียวกันกับของฉันแน่นอน
ไวยากรณ์

3

$optตัวแปรของคุณจะถูกตั้งค่าเป็นคำตัวเลือกที่สอดคล้องกับจำนวนที่ผู้ใช้ป้อน $REPLYหากคุณต้องการที่จะมองสิ่งที่ผู้ใช้พิมพ์จริงดู


1
เนื่องจากการcaseเปรียบเทียบ$optกับ "apache", "named" และ "sendmail" นั้นถูกต้องและไม่มีอะไรที่จะต้องเปลี่ยน
จัดการ

@ manatwork ยกเว้นว่า OP ต้องการให้ผู้ใช้พิมพ์คำว่า "apache", "ชื่อ" หรือ "sendmail" แทนที่จะกด 1, 2 หรือ 3
Kusalananda

น่าสนใจ $ REPLY ถือ1/ 2/ 3และ $ opt apachenamedsendmail
hold

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