你需要从用户处获得一个简单的 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 的主脚本输出也不会弄乱提示信息。
酷客网相关文章:
评论前必须登录!
注册