我想创建一个带有多选脚本的菜单。 喜欢:
1)
2)
3)
4)
5)
我可以同时选择1,3和5。
答案 0 :(得分:5)
bash
select
复合命令不直接支持多种选择,但你仍然可以基础你的解决方案,无论用户输入的是什么,都会记录在特殊的$REPLY
变量中:
#!/usr/bin/env bash
choices=( 'one' 'two' 'three' 'four' 'five' ) # sample choices
select dummy in "${choices[@]}"; do # present numbered choices to user
# Parse ,-separated numbers entered into an array.
# Variable $REPLY contains whatever the user entered.
IFS=', ' read -ra selChoices <<<"$REPLY"
# Loop over all numbers entered.
for choice in "${selChoices[@]}"; do
# Validate the number entered.
(( choice >= 1 && choice <= ${#choices[@]} )) || { echo "Invalid choice: $choice. Try again." >&2; continue 2; }
# If valid, echo the choice and its number.
echo "Choice #$(( ++i )): ${choices[choice-1]} ($choice)"
done
# All choices are valid, exit the prompt.
break
done
echo "Done."
关于select
命令通常如何工作,选择单:
man bash
并查看“复合命令”标题此答案实现自定义逻辑,如下所示:
select
命令的指定目标变量dummy
,而使用$REPLY
变量,因为Bash将其设置为用户输入的任何内容(未经验证)。 IFS=', ' read -ra selChoices <<<"$REPLY"
将用户输入的值标记为:
<<<
)向read
命令,<space>
)作为[内部]字段分隔符(IFS=...
)
-a
)selChoices
; -r
只是关闭\
字符的解释。在输入for choice in "${selChoices[@]}"; do
遍历所有令牌,即用户选择的个别号码。(( choice >= 1 && choice <= ${#choices[@]} )) || { echo "Invalid choice: $choice. Try again." >&2; continue 2; }
确保每个令牌都有效,即它是介于1和所提供选择计数之间的数字。echo "Choice #$(( ++i )): ${choices[choice-1]} ($choice)"
输出每个选项和选项编号
i
)作为前缀,使用arithmetic expansion(++i
)递增($((...))
) - 因为变量默认为{{1}在算术上下文中,第一个索引输出将是0
; 1
,即由输入的数字指示的选择字符串,递减${choices[choice-1]}
,因为Bash数组是基于1
的;请注意0
如何在数组下标中不需要choice
前缀,因为下标是在算术上下文中计算的(就像在$
内),如上所述。$(( ... ))
终止,所选数字在括号中。($choice)
;默认情况下,break
会一直提示。