Kabuk isteminden 'Evet' varyasyonlarını kabul etmenin daha iyi bir yolu


27

Bir kabuk betiğinin kullanılabilirlik testi, insanların cevabı olarak 'evet' beklenen bir soruyu nasıl cevaplayacakları konusunda farklı beklentileri olduğunu keşfetti. Aşağıdaki kod örneğindeki varyasyonlara bakın.

Elbette, bulduğum şeyden daha iyi bir yol olmalı? Okunabilir ve daha kısa formunuzda bunun üstlenilmesi nedir ?

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
Kapatmak için oy kullandı. Soru ile ilgilenmeme rağmen, büyük olasılıkla bir programlama sorusudur, bu yüzden SO'da olmalı.
Punehehe,

Bir programlama cevabı Bash
saat

3
@phunehehe: SO'ya taşınmakla aynı fikirde değilim, sadece kabuk programlamayı kabul etme geçmişimiz olduğu için değil, aynı zamanda sadece bunun nasıl yapılacağı ile ilgili bir sorun değil, aynı zamanda spesifikasyonun ne olması gerektiği ile ilgili bir soru.
Gilles 'SO- kötülük'

4
Bir zamanlar buna benzer bir senaryo yazdım. Ardından program Fransızca ve Basitleştirilmiş Çince dillerine çevrildi. Fransızca sürümünü inceledim ve istemimin "Enter oui ya da non" olarak çevrildiğini gördüm, ancak elbette kod hala "Y *" veya "N *" istedi
Ben Jackson

Yanıtlar:


15

caseGibi YEifadeler kabul edildiğinden , a kullanımı biraz eşdeğerdir ancak mükemmel değildir .

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

3
Kullanıcının amacının 'sizden' oldukça açık olduğunu söyleyebilirim.
Aeyoun

48

UNIX standardı, localeyardımcı programı kullanarak bunun için örnek kod sağlar :

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

Yerelde 'yesexpr' değeri POSIX(ve gerçek sistemlerdeki İngilizce yerel ayarları) "^[yY]". Uzatılmış düzenli bir ifade olarak yorumlanmalıdır. Ayrıca bakınız noexpr.


1
Güzel. Ama ben bir aptal gibi görünüyorum. localeBildiği tartışmaların listesini nereden bulabilirim ? Mac OS 10.5 kutumdaki man sayfası onlarda görünmüyor.
dmckee

Güzel. Lütfen tekrar kaynağa bağlayabilir misiniz?
Aeyoun

3
@dmckee yapabilirsiniz locale -k LC_MESSAGES(ve diğer LC_whatever için) veya standart tarafından tanımlananlar için buraya bakın . @Daniel Bağlantı yaptığım yerel ayar yardımcı programı sayfasından başka ne kaynak?
Random832

1
Büyük cevap, kesinlikle kabul edilen olmalı.
jlliagre 16:13

6

Bash'da kalmak (veya istemi bağımsız olarak görüntülerseniz başka bir kabuk):

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

Bu gibi yanıtları kabul ynevet olarak,  yherhangi bir şekilde (bir başlangıç alanı ile), ve wlkjzuhfodherhangi bir şekilde, olmayabilecek bağlı, fakat tipik bir kabuk istemleri ile tutarlıdır: ne olduğunu rm -i, find -okve diğerleri bunu.

Bu, uluslararasılaştırmanın tüm sorunlarından kaçınıyor: diğer dillerde, beklenen yanıtları tercüme etmeniz gerekecek. O zaman standart bir kabuk metodu yoktur; iletişim kutusuna dönebilirsiniz , ancak daha sonra komut dosyanızın yüklenmesini gerektirir (birçok dağıtımda bulunur, ancak her zaman varsayılan olarak yüklenmez).

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

3

Genelde basit bir fonksiyon kullanırım:

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

Fonksiyon sadece döner 0eğer Yya ygirilir ve 1başka bir şey girilirse. İle kullanılabilir if...fi:

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

Veya bunun gibi:

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

Çıkar -sdaktilo ne neyi görsel hikayesi olmalı.
Tom Hale

0

Sadece @faif ans değiştirildi

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

Ölçek

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.....
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.