`select`コマンドを使用してBashでメニューを印刷する

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 "*********************" 

スクリプトは、指定した有効な入力を認識せず、常に「無効なオプション」メッセージを出力します。このスクリプトで何が問題になっていますか?

コメント

  • 入力は1、2、または3ですよね?

回答

selectで表示されるメニューは次のようになります:

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コマンドには、caseではなくbreakが必要です。
  • ありがとうございます。数値オプションだとは思いませんでした。
  • ああ、私もCでプログラムしているので、すべてのセクションにbreakが必要です。 ただし、シェルスクリプト case … esac ブロックにbreakが必要になることはありません。それらを混同するのはとても簡単に起こり得ます。 🙂
  • @syntaxerror、あなたは'正解です、'はivid = “は必要ありませんcaseの場合はeefe9e6ecf “>

。ただし、selectループをエスケープするにはbreakが必要です。

  • @glennjackmanこれが欲しいですより役立つコメントになりました(次を参照)。したがって、12:55からコメントを削除することに同意していただければ幸いです。もちろん、私も同じことをします。
  • 回答

    あなたの$opt変数は、ユーザーが入力した番号に対応するオプションワードに設定されます。ユーザーが実際に入力した内容を確認したい場合は、$REPLYを確認してください。

    コメント

    • case$optを" apache "、"名前"および" sendmail "、それは正しく、何も変更する必要はありません。
    • @ manatwork、OPがユーザーに"という単語の入力を要求しない限りapache "、"名前"または" sendmail "。
    • 興味深い。 $ REPLYは1 / 2 / 3を保持し、$ optはapache / named / sendmail
    • @fred、はい、$REPLYはユーザーが入力したものであり、有効な番号の場合、$optはその番号に対応する単語になります。

    コメントを残す

    メールアドレスが公開されることはありません。 * が付いている欄は必須項目です