Linuxケースコマンド

Linuxケースコマンド

メニューリストにスペースやタブを含める方法は?

    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

selectbashメニューを表示するステートメントでは、メニューのインデントを指定できません。


コードの説明:選択した文字列を含む変数にステートメントを適用するよりも、ステートメントを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

関連情報