从shell提示接受'Yes'变体的更好方法


27

我编写的Shell脚本的可用性测试发现,人们对如何回答以“是”为答案的问题抱有不同的期望。请参见下面的代码示例中的变体。

当然,必须有一种更好的方法来解决我的问题?您对此的可读性简短形式是什么?

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上。
phunehehe 2011年


3
@phunehehe:我不同意转向SO,这不仅是因为我们有接受shell编程的历史,而且还因为它不仅是如何执行它的问题,而且还关乎规范的问题。
吉尔斯(Gilles)'所以

4
我曾经写过类似的脚本。然后将该程序翻译成法语和简体中文。我浏览了法语版本,看到提示被翻译为“ Enter oui or non”,但是代码当然仍然想要“ Y *”或“ N *”
Ben Jackson

Answers:


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
我想说的是,用户的意图很明显。
艾永2011年

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包装盒上的手册页似乎没有它们。
2011年

真好 您能否链接回源?
艾永2011年

3
您可以执行@dmckee locale -k LC_MESSAGES(以及其他LC_whatever),或者在此处查看标准定义的内容。@Daniel除了我链接的语言环境实用程序页面以外,还有哪些来源?
Random832

1
很好的答案,绝对应该被接受。
jlliagre

6

停留在bash(如果您单独显示提示,则停留在任何其他shell中):

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

这接受的响应yn为“是”, y(带有初始空格)为“否”和wlkjzuhfod“否”,这可能不是最佳选择,但与典型的shell提示是一致的:这就是方法rm -ifind -ok其他人也这样做。

这避免了整个国际化问题:用其他语言,您需要翻译预期的答复。那时没有标准的shell方法。您可以转到对话框,但是您的脚本将要求安装该对话框(许多发行版中都提供该脚本,但默认情况下并不总是安装该脚本)。

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

3

我通常使用一个简单的函数:

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

该函数仅返回0是否输入Yy以及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.....
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.