Verwenden Sie den Befehl `select`, um ein Menü in Bash zu drucken


10

Ich versuche, ein einfaches Menü mit dem selectBefehl zu implementieren . Das Skript (zu Testzwecken) lautet wie folgt:

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

Das Skript erkennt keine gültigen Eingaben, die ich gebe, und gibt immer die Meldung "Ungültige Option" aus. Was mache ich in diesem Skript falsch?


4
Ihre Eingabe ist 1, 2 oder 3, richtig?
— Enzotib

Antworten:


11

Ihr von select angezeigtes Menü sieht folgendermaßen aus:

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

Zu diesem Zeitpunkt geben Sie "1" oder "2" oder "3" ein: Sie geben das Wort nicht ein.

Außerdem selectwird eine Schleife ausgeführt, bis ein breakBefehl angezeigt wird. Sie möchten also Folgendes:

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

Wenn Sie dem Benutzer erlauben möchten, entweder die Nummer oder das Wort einzugeben, können Sie Folgendes schreiben:

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

Das Komma hat keine syntaktische Bedeutung. Es dient lediglich dazu, die Musterübereinstimmung entweder für die Variable $ REPLY (die vom Benutzer tatsächlich eingegeben wurde) oder für die Variable $ opt zu erstellen


Der selectBefehl braucht ein break, nicht case.
— Glenn Jackman

Vielen Dank! Mir war nicht klar, dass es sich um numerische Optionen handelte. Duhh!
— Sumod

Hah, ich programmiere auch in C und du brauchst breakdort in jedem Abschnitt ein. Allerdings werden Sie nie brauchen breakin einem Fall ... esac Block in einem Shell - Skript . Es kann so leicht passieren, dass sie durcheinander geraten. :-)
— Syntaxfehler

1
@syntaxerror, sind Sie richtig, Sie brauchen nicht breakzu case. Sie benötigen jedoch eine break, um der selectSchleife zu entkommen .
— Glenn Jackman

@glenn jackman Ich möchte, dass dies zu einem hilfreicheren Kommentar wird (siehe weiter unten). Es wäre also großartig, wenn Sie zustimmen würden, Ihren Kommentar von 12:55 zu löschen. Ich werde das natürlich auch mit meinen machen.
— Syntaxfehler

3

Ihre $optVariable wird auf das Optionswort gesetzt, das der vom Benutzer eingegebenen Nummer entspricht . Wenn Sie sehen möchten, was der Benutzer tatsächlich eingegeben hat, schauen Sie sich an $REPLY.


1
Angesichts der caseVergleiche $optmit "Apache", "Named" und "Sendmail" ist dies korrekt und es muss nichts geändert werden.
— Manatwork

@manatwork, es sei denn, das OP möchte, dass der Benutzer die Wörter "apache", "named" oder "sendmail" eingibt, anstatt 1, 2 oder 3 zu drücken.
— Kusalananda

Interessant. $ REPLY hält 1/ 2/ 3und $ opt hält apache/ named/sendmail
— Peter.O

@fred, ja, $REPLYist das, was der Benutzer eingegeben hat, und wenn es eine gültige Nummer war, $optist dies das Wort, das dieser Nummer entspricht.
— Kusalananda
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.