Використовуючи команду "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.
glenn jackman

Дякую! Я не усвідомлював, що це числові варіанти. Дюх!
Сумод

Так, я теж програму на C і вам потрібні breakтам у кожному розділі. Тим НЕ менше, ви ніколи не будете потребувати breakв разі ... ESAC блок в сценарії оболонки . Це може статися так легко, щоб їх змішати. :-)
синтаксичний помилок

1
@syntaxerror, ви маєте рацію, вам не потрібно breakдля case. Однак вам потрібно breakвийти з selectциклу.
Гленн Джекман

@glenn jackman Я хотів би, щоб це перетворилося на корисніший коментар (див. далі). Тож було б чудово, якби ви домовились про видалення свого коментаря з 12:55. Я зроблю те саме і зі своїм, звичайно.
синтаксичний помилок

3

Вашій $optзмінній буде встановлено слово опціону, що відповідає номеру, який вводить користувач. Якщо ви хочете подивитися, що насправді набрав користувач, подивіться $REPLY.


1
З огляду на те, що caseпорівнюється $optз "апашем", "ім'ям" та "sendmail", це правильно і нічого не потрібно міняти.
манатура

@manatwork, якщо ОП не хоче, щоб користувач вводив слова "apache", "
name

Цікаво. $ REPLY утримує 1/ 2/ 3, і $ opt утримує apache/ named/sendmail
Peter.O

@fred, так, $REPLYвсе, що вводив користувач, і якщо це було дійсне число, то $optбуде слово, відповідне цьому номеру.
Kusalananda
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.