Лучший способ принять варианты «Да» из командной строки

Проверка юзабилити сценария оболочки, который я написал, обнаружил, что у людей были разные ожидания относительно того, как ответить на вопрос, который в качестве ответа ожидал «да». См. Варианты в приведенном ниже примере кода.

Неужели должен быть лучший способ, с которым я столкнулся? Какая ваша читаемая и более короткая форма принимает это?

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
27 голосов | спросил Aeyoun 22 Maypm11 2011, 19:42:42

5 ответов


15

Использование 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
ответил sakisk 22 Maypm11 2011, 19:57:39
48

Стандарт UNIX предоставляет примерный код для этого, используя locale :

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

Значение «yesexpr» в локальном каталоге POSIX (и на локальных языках в реальных системах) - "^[yY]". Его следует интерпретировать как расширенное регулярное выражение. См. Также noexpr.

ответил Random832 22 Maypm11 2011, 22:37:15
6

Пребывание в bash (или любой другой оболочке, если вы выведете приглашение самостоятельно):

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

Это принимает ответы типа yn как да,  y (с начальным пространством) как нет, а wlkjzuhfod как нет, что может быть не оптимальным, но согласуется с типичной оболочкой подсказки: вот как rm -i, find -ok и другие делают это.

Это отбросит всю проблему интернационализации: на других языках вам нужно будет перевести ожидаемые ответы. Тогда нет стандартного метода оболочки; вы можете перейти в диалог , но тогда ваш скрипт потребует его установки (он доступен во многих дистрибутивах но не всегда устанавливаются по умолчанию).

if dialog --yesno "Choose yes" 0 0; then …
ответил Gilles 22 Maypm11 2011, 19:58:40
3

Обычно я использую простую функцию:

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

Функция возвращает 0, если Y или 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"
ответил Chuck Metcalfe 5 J0000006Europe/Moscow 2011, 13:29:35
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

Test

[email protected]:~# 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..
[email protected]:~# 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.....
ответил Rahul Patil 16 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowMon, 16 Sep 2013 15:35:56 +0400 2013, 15:35:56

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132