Bash Shell获取yes或no输入

你需要从用户处获得一个简单的 yes 或 no 作为输入,同时希望尽可能地对用户友好,尤其是不用区分大小写,如果用户直接按回车键,还能提供默认值。

解决方案

如果操作比较简单,可以使用如下示例的独立函数。

# 实例文件:func_choose

# 由用户选择并根据答案执行相应代码
# 调用方式:choose <default (y or n)> <prompt> <yes action> <no action>
# 例如:choose "y" \
#       "Do you want to play a game?" \
#       /usr/games/GlobalThermonuclearWar \
#       'printf "%b" "See you later Professor Falkin.\n"' >&2
# 返回:无
function choose {

    local default="$1"
    local prompt="$2"
    local choice_yes="$3"
    local choice_no="$4"
    local answer

    read -p "$prompt" answer
    [ -z "$answer" ] && answer="$default"

    case "$answer" in
        [yY1] ) eval "$choice_yes"
            # error check
            ;;
        [nN0] ) eval "$choice_no"
            # error check
            ;;
        *     ) printf "%b" "Unexpected answer '$answer'!" >&2 ;;
    esac
} # 函数choose结束

如果操作比较复杂,可以使用如下示例的函数,并在主代码中处理函数返回值。

# 实例文件:func_choice.1

# 由用户选择并返回标准答案。默认值的处理方式以及接下来怎么做
# 取决于主代码中choice函数之后的if/then分支
# 调用方式:choice <prompt>
# 例如:choice "Do you want to play a game?"
# 返回:全局变量CHOICE
function choice {

    CHOICE=''
    local prompt="$*"
    local answer

    read -p "$prompt" answer
    case "$answer" in
        [yY1] ) CHOICE='y';;
        [nN0] ) CHOICE='n';;
        *     ) CHOICE="$answer";;
    esac
} # 函数choice结束

如果我们返回“0”表示 no,返回“1”表示 yes,表达式if choice .. ; then 的用法则值得注意。我们将此作为练习留给你来实践。

如下代码调用了 choice 函数,提示并核实软件包的日期。假设已经设置 $THISPACKAGE,代码显示该日期,并要求用户核实。如果用户输入 y、Y,或者直接按下回车键,就接受所显示的日期。如果用户输入新的日期,代码则再次循环,继续核实日期。

# 实例文件:func_choice.2

CHOICE=''
until [ "$CHOICE" = "y" ]; do
    printf "%b" "This package's date is $THISPACKAGE\n" >&2
    choice "Is that correct? [Y/,<New date>]: "
    if [ -z "$CHOICE" ]; then
        CHOICE='y'
    elif [ "$CHOICE" != "y" ]; then
        printf "%b" "Overriding $THISPACKAGE with $CHOICE\n"
        THISPACKAGE=$CHOICE
    fi
done

# 在此构建软件包

接下来看看处理 yes 或 no 的其他方法。仔细阅读提示信息,注意默认操作。在两种情况下,用户都可以直接按回车键,脚本将采用程序员安排好的默认处理方式:

# 如果用户输入'n'(不区分大小写)之外的任何内容,则会看到错误日志
choice "Do you want to look at the error logfile? [Y/n]: "
if [ "$CHOICE" != "n" ]; then
    less error.log
fi

# 如果用户输入'y'(不区分大小写)之外的任何内容,则看不到消息日志
choice "Do you want to look at the message logfile? [y/N]: "
if [ "$CHOICE" = "y" ]; then
    less message.log
fi

最后,下例中的函数会要求用户输入(有可能不存在)。

# 实例文件:func_choice.3

choice "Enter your favorite color, if you have one: "
if [ -n "$CHOICE" ]; then
    printf "%b" "You chose: $CHOICE\n"
else
    printf "%b" "You do not have a favorite color.\n"
fi

讨论

在脚本编程中,要求用户做出选择往往是必不可少的。要想获取任意输入,参考获取用户输入

如果用户可能做出的选择及相应处理代码非常直观,那么第一个独立函数更易于使用,但可能不够灵活。第二个函数在主代码中做了更多处理,因而灵活性更好。

注意,我们将用户提示发送到了 STDERR,这样一来,就算重定向出现在 STDOUT 的主脚本输出也不会弄乱提示信息。

酷客网相关文章:

赞(0)

评论 抢沙发

评论前必须登录!