2つの機能を持つテーマ用のツールスクリプトを作成しています:更新の確認、テーマの再インストール
だからここに選択メニューのコードがあります:
PS3='Choose an option: '
options=("Check for update" "Reinstall theme")
select opt in "${options[@]}"
do
case $opt in
"Check for update")
echo "Checking update"
;;
"Reinstall theme")
echo "Reinstalling"
;;
*) echo invalid option;;
esac
done
走るとこんな感じ
1) Check for update
2) Reinstall theme
Choose an option:
1と入力して入力すると、更新の確認コマンドが実行されます
問題は、スクリプトの実行が終了すると、メニューではなく「オプションを選択:」が再表示されることです。したがって、メニューがないと(特に長いスクリプトの後)、ユーザーが選択しにくくなる可能性があります。
1) Check for update
2) Reinstall theme
Choose an option: 1
Checking update
Choose an option:
オプションを実行した後でメニューを再表示するにはどうすればよいですか
私はあなたが本当にこのようなものを望んでいると思います:
check_update () {
echo "Checking update"
}
reinstall_theme () {
echo "Reinstalling theme"
}
while true; do
options=("Check for update" "Reinstall theme")
echo "Choose an option:"
select opt in "${options[@]}"; do
case $REPLY in
1) check_update; break ;;
2) reinstall_theme; break ;;
*) echo "What's that?" >&2
esac
done
echo "Doing other things..."
echo "Are we done?"
select opt in "Yes" "No"; do
case $REPLY in
1) break 2 ;;
2) break ;;
*) echo "Look, it's a simple question..." >&2
esac
done
done
最初のcase
ステートメントを小さく保つために、タスクを個別の関数に分けました。 case
ステートメントではオプション文字列ではなく$REPLY
も使用しました。これは短いため、変更しても、両方の場所で更新することを忘れても壊れないためです。また、スクリプトのselect
呼び出しに影響する可能性があるため、PS3
には触れないように選択しています。別のプロンプトが必要な場合は、一度設定してそのままにします(多分PS3="Your choice: "
)。これにより、複数の質問を含むスクリプトがより統一された感じになります。
ユーザーが完了するまですべてを繰り返す外部ループを追加しました。最初のselect
ステートメントで質問を再表示するには、このループが必要です。
break
をcase
ステートメントに追加しました。そうしないと、スクリプトを中断する以外に終了する方法がありません。
select
の目的は、ユーザーから1つの質問に対する回答を得ることであり、実際には(それ自体が)スクリプトのメインイベントループになることではありません。一般に、select
-case
は実際に変数を設定するか、関数を呼び出してから続行する必要があります。
最初のselect
に「Quit」オプションを組み込んだ短いバージョン:
check_update () {
echo "Checking update"
}
reinstall_theme () {
echo "Reinstalling theme"
}
while true; do
options=("Check for update" "Reinstall theme" "Quit")
echo "Choose an option: "
select opt in "${options[@]}"; do
case $REPLY in
1) check_update; break ;;
2) reinstall_theme; break ;;
3) break 2 ;;
*) echo "What's that?" >&2
esac
done
done
echo "Bye bye!"
私はこのトリックを使います:
options=("First option" "Second option" "Quit")
PS3="So what? "
select opt in "${options[@]}"
do
case $opt in
"First option")
echo "First option"
;;
"Second option")
echo "Second option"
;;
"Quit")
echo "We are done..."
break
;;
*)
PS3="" # this hides the Prompt
echo asdf | select foo in "${options[@]}"; do break; done # dummy select
PS3="So what? " # this displays the common Prompt
;;
esac
done
Doループは無限であり、selectステートメントはその外側にあります。スクリプトは、selectステートメントを1回実行した後、$ optケースの繰り返しを確認するdoループチェックを続けます。私の推奨は、次のようなケースステートメントの後に休憩を入れることです。
esac
break
done
次に、スクリプト全体を何度も繰り返したい場合は、selectステートメントからdoneステートメントまでをすべて囲む別のループを作成します。