Med kommandot `välj för att skriva ut en meny i Bash

Jag försöker implementera en enkel meny med select kommando. Skriptet (för teständamål) är som följer:

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

Skriptet känner inte igen några giltiga ingångar jag ger och skriver alltid ut meddelandet ”Ogiltigt alternativ”. Vad gör fel i det här skriptet?

Kommentarer

  • Din inmatning är 1, 2 eller 3, eller hur?

Svar

Din meny som visas med select kommer att se ut:

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

För närvarande anger du ” 1 ”eller” 2 ”eller” 3 ”: du skriver inte ordet.

Dessutom kommer select att slinga tills den ser en break, så du vill ha det här:

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

Om du vill tillåta användaren att ange antingen numret eller ordet, du kan skriva detta:

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 

Kommat har ingen syntaktisk betydelse, det är bara där för att kunna mönstra matchning på antingen $ REPLY variabel (vilket är vad användaren faktiskt skrev) eller $ opt-variabeln

Kommentarer

  • select kommandot behöver ett break, inte case.
  • Tack! Jag insåg inte att det var numeriska alternativ. Duhh!
  • Hah, jag programmerar också i C och du behöver en break där i varje avsnitt. Du kommer emellertid aldrig att behöva ett break i ett fall … esac -block i ett skalskript . Det kan hända så lätt att blanda dem ihop. 🙂
  • @syntaxerror, du ' har rätt, du behöver ' t behöver break för case. Du behöver dock en break för att undkomma select -slingan.
  • @glenn jackman Jag skulle vilja ha det här förvandlats till en mer användbar kommentar (se nästa). Så det skulle vara bra om du gick med på att radera din kommentar från 12:55. Jag kommer naturligtvis att göra detsamma med min.

Svar

Din $opt -variabeln kommer att ställas in till det alternativord som motsvarar numret som användaren matar in. Om du vill titta på vad användaren faktiskt skrev, titta på $REPLY.

Kommentarer

  • Med tanke på att case jämför $opt mot " apache ", " med namnet " och " sendmail ", det är korrekt och ingenting behöver ändras.
  • @manatwork, såvida inte OP vill att användaren ska skriva in orden " apache ", " med namnet " eller " sendmail " istället för att trycka på 1, 2 eller 3.
  • Intressant. $ REPLY innehar 1 / 2 / 3, och $ opt håller apache / named / sendmail
  • @fred, ja, $REPLY är vad användaren skrev, och om det var ett giltigt nummer kommer $opt att vara det ord som motsvarar det numret.

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *