2016-11-06 14 views
1

私はbashselectを使用して、既存の2つの間に新しい選択肢を追加するとオプション番号が自動的に調整される多肢選択ダイアログを作成します。select:非公開の文字入力を受け入れる

select choice in command1 command2 command3; do 
    $choice 
    break 
done 

自体で実行したコマンドとは異なる何かを表示するには、私は連想配列

declare -A choices=(
    [Option 1]=command1 
    [Option 2]=command2 
    [Option 3]=command3 
) 
select choice in "${!choices[@]}" exit ; do 
    [[ $choice == exit ]] && break 
    ${choices[$choice]} 
done 

私はこの方法を好きではない事を宣言すると言われてきたが、オプションがするということですexitは、番号が付いた選択肢として表示されます。私は

PS3="Select the desired option (q to quit): " 

ような何かを達成し、 selectは有効な入力として、 12または 3のほか、 qを受け入れるようにしたいと思います。

連想配列は、入力がインデックスとして使用されているという事実に問題があるため、入れ子になったcaseに切り替えました。この方法では、私はまた、複数のコマンドに

PS3="Select the desired option (q to quit): " 
select choice in "Option 1" "Option 2" "Option 3"; do 
    case $choice in 
     "Option 1") command1a 
        command1b 
        break;; 
     "Option 2") command2a 
        command2b 
        break;; 
     "Option 3") command3a 
        command3b 
        break;; 
     q)   echo "Bye!" 
        break;; 
    esac 
done 

を保存するために別々の機能を宣言する必要はありません今そこに非数値(またはオーバーレンジ)入力に関しては問題はありませんが、入力としてqがありますまだ認識されていません。 defaultの場合、*)を定義している場合はそれを実行します。定義しなかった場合は、再度プロンプトを表示します。

私がしようとしていることを達成する方法はありますか?

答えて

1

$REPLY変数を使用(内容を確認)してください。

例:

declare -A choices=(
    [Show the date]=show_date 
    [Print calendar]=print_cal 
    [Say hello]=say_hello 
) 

show_date() { 
    date 
} 
print_cal() { 
    cal 
} 
say_hello() { 
    echo "Hello $USER" 
} 

PS3="Select the desired option (q to quit): " 
select choice in "${!choices[@]}" 
do 
    case "$choice" in 
    '') # handling the invalid entry - e.g. the "q" 
     # in a case of an invalid entry, the $choice is en empty(!) string 
     # checking the content of the entered line can be done using the $REPLY 
     case "$REPLY" in 
      q|Q) echo "Bye, bye - quitting...."; exit;; 
      *) echo "INVALID choice <$REPLY> - try again";; 
     esac 
     ;; 
    *) 
     #valid user input 
     ${choices[$choice]} 
     ;; 
    esac 
done 

または短くはなく、

declare -A choices=(
    [Show the date]=show_date 
    [Print calendar]=print_cal 
    [Say hello]=say_hello 
) 

show_date() { 
    date 
} 
print_cal() { 
    cal 
} 
say_hello() { 
    echo "Hello $USER" 
} 

PS3="Select the desired option (q to quit): " 
select choice in "${!choices[@]}" 
do 
    case "$REPLY" in 
    q|Q) echo "Bye, bye - quitting...."; exit;; 
    1|2|3) ${choices[$choice]} ;; 
    *) echo "INVALID choice <$REPLY> - try again";; 
    esac 
done 
+0

として柔軟これは素晴らしいです!あなたは素晴らしいです!私は学んだような気がします。最後のことがまだあります: '$ REPLY'を直接扱うメソッドが"柔軟ではない "と言うとどういう意味ですか?有効な入力に対応するすべての数値を手動で指定する必要があるからですか? –

関連する問題