select:接受未列出的字符输入
select: accept an unlisted, char input
我正在使用 bash
select
创建一个多选对话框,当我在两个现有选项之间添加新选项时,选项编号会自动调整。
select choice in command1 command2 command3; do
$choice
break
done
要显示与本身执行的命令不同的内容,有人告诉我声明一个关联数组
declare -A choices=(
[Option 1]=command1
[Option 2]=command2
[Option 3]=command3
)
select choice in "${!choices[@]}" exit ; do
[[ $choice == exit ]] && break
${choices[$choice]}
done
我不喜欢这种方式的一点是,exit
的选项被视为编号选择。我想实现类似
的目标
PS3="Select the desired option (q to quit): "
并使 select
除了 1
、2
或 3
之外,还接受 q
作为有效输入。
关联数组导致输入用作索引的事实出现问题,因此我切换到嵌套 case
。这样,我也不必声明单独的函数来存储多个命令
PS3="Select the desired option (q to quit): "
select choice in "Option 1" "Option 2" "Option 3"; do
case $choice in
"Option 1") command1a
command1b
break;;
"Option 2") command2a
command2b
break;;
"Option 3") command3a
command3b
break;;
q) echo "Bye!"
break;;
esac
done
现在没有关于非数字(或超范围)输入的问题,但是 q
作为输入仍然无法识别。它属于 default
的情况,如果我定义了它,则执行 *)
,如果我没有定义,则简单地再次提示。
有什么方法可以实现我想要做的事情吗?
只需使用(检查内容)$REPLY
变量。
示例:
declare -A choices=(
[Show the date]=show_date
[Print calendar]=print_cal
[Say hello]=say_hello
)
show_date() {
date
}
print_cal() {
cal
}
say_hello() {
echo "Hello $USER"
}
PS3="Select the desired option (q to quit): "
select choice in "${!choices[@]}"
do
case "$choice" in
'') # handling the invalid entry - e.g. the "q"
# in a case of an invalid entry, the $choice is en empty(!) string
# checking the content of the entered line can be done using the $REPLY
case "$REPLY" in
q|Q) echo "Bye, bye - quitting...."; exit;;
*) echo "INVALID choice <$REPLY> - try again";;
esac
;;
*)
#valid user input
${choices[$choice]}
;;
esac
done
或更短,但不那么灵活
declare -A choices=(
[Show the date]=show_date
[Print calendar]=print_cal
[Say hello]=say_hello
)
show_date() {
date
}
print_cal() {
cal
}
say_hello() {
echo "Hello $USER"
}
PS3="Select the desired option (q to quit): "
select choice in "${!choices[@]}"
do
case "$REPLY" in
q|Q) echo "Bye, bye - quitting...."; exit;;
1|2|3) ${choices[$choice]} ;;
*) echo "INVALID choice <$REPLY> - try again";;
esac
done
我正在使用 bash
select
创建一个多选对话框,当我在两个现有选项之间添加新选项时,选项编号会自动调整。
select choice in command1 command2 command3; do
$choice
break
done
要显示与本身执行的命令不同的内容,有人告诉我声明一个关联数组
declare -A choices=(
[Option 1]=command1
[Option 2]=command2
[Option 3]=command3
)
select choice in "${!choices[@]}" exit ; do
[[ $choice == exit ]] && break
${choices[$choice]}
done
我不喜欢这种方式的一点是,exit
的选项被视为编号选择。我想实现类似
PS3="Select the desired option (q to quit): "
并使 select
除了 1
、2
或 3
之外,还接受 q
作为有效输入。
关联数组导致输入用作索引的事实出现问题,因此我切换到嵌套 case
。这样,我也不必声明单独的函数来存储多个命令
PS3="Select the desired option (q to quit): "
select choice in "Option 1" "Option 2" "Option 3"; do
case $choice in
"Option 1") command1a
command1b
break;;
"Option 2") command2a
command2b
break;;
"Option 3") command3a
command3b
break;;
q) echo "Bye!"
break;;
esac
done
现在没有关于非数字(或超范围)输入的问题,但是 q
作为输入仍然无法识别。它属于 default
的情况,如果我定义了它,则执行 *)
,如果我没有定义,则简单地再次提示。
有什么方法可以实现我想要做的事情吗?
只需使用(检查内容)$REPLY
变量。
示例:
declare -A choices=(
[Show the date]=show_date
[Print calendar]=print_cal
[Say hello]=say_hello
)
show_date() {
date
}
print_cal() {
cal
}
say_hello() {
echo "Hello $USER"
}
PS3="Select the desired option (q to quit): "
select choice in "${!choices[@]}"
do
case "$choice" in
'') # handling the invalid entry - e.g. the "q"
# in a case of an invalid entry, the $choice is en empty(!) string
# checking the content of the entered line can be done using the $REPLY
case "$REPLY" in
q|Q) echo "Bye, bye - quitting...."; exit;;
*) echo "INVALID choice <$REPLY> - try again";;
esac
;;
*)
#valid user input
${choices[$choice]}
;;
esac
done
或更短,但不那么灵活
declare -A choices=(
[Show the date]=show_date
[Print calendar]=print_cal
[Say hello]=say_hello
)
show_date() {
date
}
print_cal() {
cal
}
say_hello() {
echo "Hello $USER"
}
PS3="Select the desired option (q to quit): "
select choice in "${!choices[@]}"
do
case "$REPLY" in
q|Q) echo "Bye, bye - quitting...."; exit;;
1|2|3) ${choices[$choice]} ;;
*) echo "INVALID choice <$REPLY> - try again";;
esac
done