Bash में मेनू प्रिंट करने के लिए `select` कमांड का उपयोग करना


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 चर (जो कि वास्तव में उपयोगकर्ता द्वारा टाइप किया गया है) या $ ऑप्ट वैरिएबल पर पैटर्न मिलान करने में सक्षम है


selectआदेश एक की जरूरत है break, नहीं case
ग्लेन जैकमैन

धन्यवाद! मुझे महसूस नहीं हुआ कि यह संख्यात्मक विकल्प था। Duhh!
सुमोद

हह, मैं भी सी में प्रोग्राम करता हूं और, आपको breakहर सेक्शन में इसकी जरूरत है । हालांकि, आपको breakएक मामले में कभी भी आवश्यकता नहीं होगी ... शेल स्क्रिप्ट में एस्क ब्लॉक । उन्हें मिलाया जाना इतनी आसानी से हो सकता है। :-)
वाक्यविन्यास

1
@syntaxerror, तो आप सही हैं, तो आप की जरूरत नहीं है कर रहे हैं breakके लिए case। हालांकि, आपको लूप breakसे बचने की आवश्यकता है select
ग्लेन जैकमैन

@ ग्लेन जैकमैन मैं चाहूंगा कि यह एक अधिक उपयोगी टिप्पणी में बदल जाए (आगे देखें)। इसलिए यह बहुत अच्छा होगा यदि आप अपनी टिप्पणी को 12:55 से हटाने पर सहमत हों। मैं भी ऐसा ही करूंगा।
वाक्यविन्यास

3

आपका $optचर उस नंबर के लिए विकल्प शब्द पर सेट किया जाएगा जो उपयोगकर्ता इनपुट के अनुसार होता है। यदि आप यह देखना चाहते हैं कि उपयोगकर्ता वास्तव में क्या टाइप कर रहा है, तो देखें $REPLY


1
यह देखते हुए कि "अपाचे", "नाम" और "सेंडमेल" के खिलाफ caseतुलना $opt, यह सही है और कुछ भी नहीं बदलना है।
मैनटवर्क

@manatwork शब्दों "अपाचे" में टाइप करने के उपयोगकर्ता जब तक ओ पी चाहता है, "नाम" या "sendmail" बल्कि 1, 2 या 3 दबाने से
Kusalananda

दिलचस्प। $ REPLY रखती है 1/ 2/ 3, और $ ऑप्ट रखती है apache/ named/sendmail
पीटर।

@fred, हाँ, $REPLYवह है जो भी उपयोगकर्ता टाइप करता है, और यदि यह एक वैध संख्या थी तो $optउस संख्या के अनुरूप शब्द होगा।
Kusalananda
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.