效果如下:
废话不多说,上代码:
bash
#!/bin/bash
options=("111" "222" "333" "444") # 选项列表
options_index=0 # 默认选中第一个选项
options_len=${#options[@]}
echo "请用上下方向键进行选择,空格键选中/取消,回车键确认结果"
# 定义一个数组来存储选中的结果
selected=()
for ((i=0; i<${options_len}; i++));do
selected[$i]=0
done
# 渲染选项列表
render_options() {
for i in "${!options[@]}"; do
# 首先渲染已经选中的选项
if [ ${selected[$i]} -eq 1 ];then
if [ $i -eq $options_index ]; then
echo -e "\033[1;41;34m${options[$i]}\033[0m" # 已选中,已选择
else
echo -e "\033[1;41;33m${options[$i]}\033[0m" # 已选中,未选择
fi
elif [ $i -eq $options_index ]; then
echo -e "\033[1;34m${options[$i]}\033[0m" # 未选中,已选择
else
echo "${options[$i]}" # 未选中,未选择
fi
done
}
# 初始渲染
render_options
# 为了让read能读到空格键
IFS_store=$IFS
IFS=''
while true; do
read -s -n 1 key # 读取单个按键输入,不显示在终端上
case $key in
"A") # 上箭头键
if [ $options_index -gt 0 ]; then
options_index=$((options_index - 1))
# 在第一行按上键,到最后一行
elif [ $options_index -eq 0 ]; then
options_index=$((${options_len} - 1))
fi
;;
"B") # 下箭头键
if [ $options_index -lt $(( ${options_len} - 1 )) ]; then
options_index=$((options_index + 1))
# 在最后一行按下键,到第一行
elif [ $options_index -eq $(( ${options_len} - 1 )) ]; then
options_index=0
fi
;;
" ") # 空格键
# selected[$options_index]的值,0、1切换
selected[$options_index]=$((1 - ${selected[$options_index]}))
;;
"") # 回车键
break
;;
esac
tput cuu ${options_len} # 光标移动回到选项列表的开头
tput ed # 清除当前行
render_options # 重新渲染选项列表
done
# 恢复IFS变量
IFS=$IFS_store
# 最后选中的所有结果
result=()
for ((i=0; i<options_len; i++));do
if [ ${selected[$i]} -eq 1 ];then
result+=(${options[$i]})
fi
done
echo "选中:${result[@]}"