我在这样的bash脚本中提示问题:
optionsAudits=("Yep" "Nope")
echo "Include audits?"
select opt in "${optionsAudits[@]}"; do
case $REPLY in
1) includeAudits=true; break ;;
2) includeAudits=false; break ;;
"\n") echo "You pressed enter"; break ;; # <--- doesn't work
*) echo "What's that?"; exit;;
esac
done
按下Enter键后,如何选择默认选项?该"\n"
案件不赶回车键。
为了补充Aserre的有用答案,该答案解释了您的代码问题,并提供了有效的解决方法,背景信息以及select
允许空输入的通用,可重用的自定义实现:
明确说明一下:select
它本身会忽略空输入(只需按Enter),而只是重新提示-用户代码甚至无法响应运行。
实际上,select
使用空字符串向用户代码表示输入了无效的选择。
也就是说,如果输出变量- $opt
,诠释这种情况下-是空的内部select
说法,言外之意就是无效的选择指数由用户输入。
的输出变量接收所选择的选项的文本-无论是'Yep'
或'Nope'
在这种情况下-不是索引由用户键入。
(相比之下,你的代码检$REPLY
代替的输出变量,它正好包含用户键入的内容,这是该指数在一个有效的选择情况,但可能含有额外的开头和结尾的空格)。
请注意,倘若你不希望允许空的输入,你可以简单地表示在提示文本,用户^C
(Ctrl+C)可以用来中止提示。
select
函数,也接受空输入以下功能紧密模拟了该select
操作,同时还允许空输入(只需按Enter)。请注意,该函数将拦截无效输入,打印警告并重新提示:
# Custom `select` implementation that allows *empty* input.
# Pass the choices as individual arguments.
# Output is the chosen item, or "", if the user just pressed ENTER.
# Example:
# choice=$(selectWithDefault 'one' 'two' 'three')
selectWithDefault() {
local item i=0 numItems=$#
# Print numbered menu items, based on the arguments passed.
for item; do # Short for: for item in "$@"; do
printf '%s\n' "$((++i))) $item"
done >&2 # Print to stderr, as `select` does.
# Prompt the user for the index of the desired item.
while :; do
printf %s "${PS3-#? }" >&2 # Print the prompt string to stderr, as `select` does.
read -r index
# Make sure that the input is either empty or that a valid index was entered.
[[ -z $index ]] && break # empty input
(( index >= 1 && index <= numItems )) 2>/dev/null || { echo "Invalid selection. Please try again." >&2; continue; }
break
done
# Output the selected item, if any.
[[ -n $index ]] && printf %s "${@: index:1}"
}
您可以这样称呼它:
# Print the prompt message and call the custom select function.
echo "Include audits (default is 'Nope')?"
optionsAudits=('Yep' 'Nope')
opt=$(selectWithDefault "${optionsAudits[@]}")
# Process the selected item.
case $opt in
'Yep') includeAudits=true; ;;
''|'Nope') includeAudits=false; ;; # $opt is '' if the user just pressed ENTER
esac
注意:此代码不能解决问题,但是显示了该select
语句的更多惯用用法。与原始代码不同,如果做出了无效的选择,此代码将重新显示提示:
optionsAudits=("Yep" "Nope")
echo "Include audits (^C to abort)?"
select opt in "${optionsAudits[@]}"; do
# $opt being empty signals invalid input.
[[ -n $opt ]] || { echo "What's that? Please try again." >&2; continue; }
break # a valid choice was made, exit the prompt.
done
case $opt in # $opt now contains the *text* of the chosen option
'Yep')
includeAudits=true
;;
'Nope') # could be just `*` in this case.
includeAudits=false
;;
esac
注意:
该case
语句已移出该select
语句,因为后者现在保证只能进行有效输入。
该case
语句测试输出变量($opt
)而不是原始用户输入($REPLY
),并且该变量包含选择文本,而不是其索引。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句