我的bash脚本中有选择菜单,我很好奇是否有一种方法可以简化和压缩菜单而不重复我自己。我尝试了许多不同的方法都没有用,有人知道浓缩这种代码的好方法吗?
PS3="some menu"
options=("option 1" "option2" "option3" "exit")
select opt in "${options[@]}"
do
case $opt in
"option1")
something
;;
"option 1")
something
;;
"option 2")
something
;;
"exit")
;;
*) echo "invalid option $REPLY";;
esac
read -p "Press Enter to continue"
clear
return 1
done
PS3="some menu 2"
options=("option 1" "option2" "exit")
select opt in "${options[@]}"
do
case $opt in
"option 1")
something
;;
"option 2")
something
;;
"exit")
exit
;;
*) echo "invalid option $REPLY";;
esac
read -p "Press Enter to continue"
clear
return 1
done
我想压缩代码而不在代码中重复多个菜单。
答案 0 :(得分:1)
将其放入函数中并调用两次,如下所示:
#!/usr/bin/env bash
prompt() {
local opt
local -A isExpected
local -a options
PS3="$1"
shift
options=()
for opt; do
isExpected["$opt"]=1
options+=("$opt")
done
isExpected["exit"]=1
options+=("exit")
select opt in "${options[@]}"
do
if (( "${isExpected[$opt]}" )); then
case $opt in
"option 1")
something
;;
"option 2")
something
;;
"option 3")
something
;;
"exit")
;;
*) printf 'invalid option "%s"\n' "$REPLY" >&2;;
esac
else
printf 'unexpected option "%s"\n' "$opt" >&2
fi
read -r -p "Press Enter to continue"
clear
return 1
done
}
prompt "some menu" "option 1" "option 2" "option 3"
prompt "some menu 2" "option 1" "option 2"
很显然,您可以将所有常用选项移到prompt()
中,就像我对"exit"
所做的那样。如果显示的选项顺序无关紧要,那么您可以摆脱isExpected[]
,而只使用一个关联数组来容纳options
并使用${!options[@]}"
进行选择。
答案 1 :(得分:0)
您可以使用调度表,将选项文本映射到该选项的函数。这要求使用local -n
namerefs
fn_a1() { echo "do something here for option a1"; }
fn_a2() { echo "do something here for option a2"; }
fn_a3() { echo "do something here for option a3"; }
fn_b1() { echo "do something here for option b1"; }
fn_b2() { echo "do something here for option b2"; }
prompt() {
local PS3="$1: "
local -n _options=$2 _dispatch=$3
select opt in "${_options[@]}"; do
if [[ -v _dispatch["$opt"] ]]; then
"${_dispatch[$opt]}"
break
fi
done
}
declare -A dispatch_table
declare -a options
options=( "option a1" "option a2" "option a3" exit )
dispatch_table=(
["option a1"]=fn_a1
["option a2"]=fn_a2
["option a3"]=fn_a3
["exit"]=exit
)
prompt "some menu" options dispatch_table
options=( "option b1" "option b2" exit )
dispatch_table=(
["option b1"]=fn_b1
["option b2"]=fn_b2
["exit"]=exit
)
prompt "some menu 2" options dispatch_table
我将选项作为单独的数组发送,以便可以控制菜单的顺序:在关联数组的键上进行迭代没有固有的顺序。