シェルプロンプトから「はい」のバリエーションを受け入れるより良い方法


27

私が書いたシェルスクリプトのユーザビリティテストは、答えとして「はい」を期待する質問に答える方法について、人々が異なる期待を持っていることを発見しました。以下のコード例のバリエーションを参照してください。

きっと、私が思いついたものより良い方法があるに違いありませんか?あなたは何で読める短い形式の本を取るには?

read -p 'Answer this question with yes: ' answer
if [ "$answer" = 'Y'
  -o "$answer" = 'YES'
  -o "$answer" = 'Yes'
  -o "$answer" = 'y'
  -o "$answer" = 'yes'
  -o some-alternate-condition ]; then

  echo 'Surely this can be written better?'
fi

2
閉じるために投票しました。私はこの質問に興味がありますが、おそらくプログラミングの質問の方が多いので、SOにすべきです。
プネヘヘ

プログラミングの答えのようなものであるかもしれない配列要素が存在するかどうかを確認します。bash
phunehehe

3
@phunehehe:SOに移行することに同意しません。シェルプログラミングを受け入れてきた歴史があるだけでなく、その方法だけでなく、仕様がどうあるべきかという問題もあるからです。
ジル 'SO-悪であるのをやめる'

4
私はそのようなスクリプトを一度書きました。その後、プログラムはフランス語と簡体字中国語に翻訳されました。フランス語版をざっと読んで、プロンプトが「Enter oui or non」に翻訳されたのを見ましたが、もちろんコードはまだ「Y *」または「N *」を望んでいました
ベンジャクソン

回答:


15

aを使用することcaseは多少同等ですが、次のようなステートメントYEが受け入れられるため完全ではありません。

read -p 'Answer this question with yes: ' answer
case "${answer}" in
    [yY]|[yY][eE][sS])
        echo 'Surely this can be written better?' ;;
esac

3
ユーザーの意図は「はい」からかなり明確だと思います。
Aeyoun

48

UNIX標準では、localeユーティリティを使用してこのためのサンプルコードを提供しています

if printf "%s\n" "$response" | grep -Eq "$(locale yesexpr)"
then
    affirmative processing goes here
else
    non-affirmative processing goes here
fi

POSIXロケール(および実際のシステムの英語ロケール)での 'yesexpr'の値は"^[yY]"です。拡張正規表現として解釈されます。noexprも参照してください。


1
いいね しかし、私は馬鹿のようです。locale知っている引数のリストはどこにありますか?私のMac OS 10.5ボックスのマニュアルページには、それらがないようです。
dmckee

いいね ソースにリンクしてください。
Aeyoun

3
@dmckeeを使用してlocale -k LC_MESSAGES(および他のLC_whateverについて)、標準で定義されているものについてはこちらを参照してください。@Daniel私がリンクしたロケールユーティリティページ以外のソースは何ですか?
Random832

1
素晴らしい答えは、間違いなく受け入れられるべきです。
jlliagre

6

bash(または、プロンプトを個別に表示する場合は他のシェル)にとどまる:

case $answer in
  [Yy]*) echo Ok;;
  *) echo "Can't you read? I said to say yes.";;
esac

これは、のような応答受け付けynはい、 yいいえなど、および(初期宇宙で)wlkjzuhfodそれは方法は次のとおりです。最適ではなく、典型的なシェルプロンプトと一致していないことがないように、rm -ifind -okおよび他の人がそれを行うに。

これにより、国際化の問題全体が回避されます。他の言語では、予想される応答を翻訳する必要があります。その場合、標準のシェルメソッドはありません。ダイアログに切り替えることができますが、スクリプトをインストールする必要があります(多くのディストリビューションで利用可能ですが、デフォルトで常にインストールされるわけではありません)。

if dialog --yesno "Choose yes" 0 0; then 

3

私は通常、単純な関数を使用します。

Confirm() { read -sn 1 -p "$* [Y/N]? "; [[ ${REPLY:0:1} = [Yy] ]]; }

この関数は0Yまたはyが入力され、1他の何かが入力された場合にのみ戻ります。以下で使用できますif...fi

if Confirm "Type y or n"; then
echo "You typed y"
else
echo "You typed n"
fi

またはちょうどこのように:

Confirm "Type y" && echo "You typed y"

脱いで、-s入力された内容の視覚的な履歴があります。
トム・ヘイル

0

@faif ansを再変更するだけです

YesOrNo() {
        while :
        do
                read -p 'Do you want to Continue (yes/no?): ' answer
                case "${answer}" in
                    [yY]|[yY][eE][sS]) exit 0 ;;
                        [nN]|[nN][oO]) exit 1 ;;
                esac
        done
}


if $( YesOrNo ); then
        echo "Ans is yes.. Do something....."
else
        echo "Ans is No... skip.."
fi

テスト

root@ubuntu:~# bash confirm.sh
Do you want to Continue (yes/no?):  # if Blank Enter then ask again
Do you want to Continue (yes/no?):
Do you want to Continue (yes/no?):
Do you want to Continue (yes/no?): no
Ans is No... skip..
root@ubuntu:~# bash confirm.sh
Do you want to Continue (yes/no?):
Do you want to Continue (yes/no?):
Do you want to Continue (yes/no?): ye
Do you want to Continue (yes/no?): yes
Ans is yes.. Do something.....
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.