メニューリストにスペースやタブを含める方法は?
PS3='Please enter your choice: '
options=("Option 1" "Option 2" "Quit")
select opt in "${options[@]}"
do
case $opt in
"Option 1")
echo "Your choise is 1"
;;
"Option 2")
echo "Your choise is 2"
;;
"Quit")
break
;;
*) echo "Invalid option;;
esac
done
わかりました:
[user@Server:/home/user] ./test.sh
1) Option 1
2) Option 2
3) Option 3
4) Quit
Please enter your choice:
しかし、私は次のようなものが欲しい:
[user@Server:/home/user] ./test.sh
1) Option 1
2) Option 2
3) Option 3
4) Quit
Please enter your choice:
アイデアはありますか?
答え1
select
少なくとも複数の列リストを必要とするオプションが多すぎない限り、手動で(およそ)ディスプレイを再実装して微調整することはそれほど難しくありません。
#!/bin/bash
# print the prompt from $1, and a menu of the other arguments
choose() {
local prompt=$1
shift
local i=0
for opt in "$@"; do
# we have to do the numbering manually...
printf " %2d) %s\n" "$((i += 1))" "$opt"
done
read -p "$prompt: "
}
options=("Foo" "Bar" "Quit")
while choose 'Please enter your choice' "${options[@]}"; do
case $REPLY in
1) echo "you chose 'foo'" ;;
2) echo "you chose 'bar'";;
3) echo 'you chose to quit'; break;;
*) echo 'invalid choice';;
esac
done
もちろん、これは配列キー(インデックス)を考慮してカウンタを実行するのではなく、メニューのオプションとしてレンダリングするように拡張できます。
答え2
select
bash
メニューを表示するステートメントでは、メニューのインデントを指定できません。
コードの説明:選択した文字列を含む変数にステートメントを適用するよりも、ステートメントをcase
実行する方が簡単です。$REPLY
文字列を2回入力する必要はありません。
例えば
select opt in "${options[@]}"
do
case $REPLY in
1)
echo "Your choice is 1"
;;
2)
echo "Your choice is 2"
;;
3)
break
;;
*) echo 'Invalid option' >&2
esac
done
または、この具体的な例では
select opt in "${options[@]}"
do
case $REPLY in
[1-2])
printf 'Your choice is %s\n' "$REPLY"
;;
3)
break
;;
*) echo 'Invalid option' >&2
esac
done