我想在 bash(macOS 上的版本 3.2)中实现一个选择菜单,它将输出如下内容:
Select a fruit:
0 Nothing
1 A banana
2 An orange
当用户选择一个项目时,我希望能够运行关联的 bash 脚本。为此,我需要类似二维数组的东西,但如果我没记错的话,它在 bash 中不存在。我考虑过在一个主数组中使用多个数组。然后我将使用循环向用户显示菜单:
#!/usr/bin/env bash
item_nothing=("0" "Nothing" "")
item_banana=("1" "A banana" "select_banana.sh")
item_orange=("2" "An orange" "select_orange.sh")
items=(
"item_nothing"
"item_banana"
"item_orange"
)
printf "Select a fruit:\n"
for item in "${items[@]}"; do
printf "$(\$$item[0])"
printf "$(\$$item[1])\n"
# $(\$$item[2])
done
当我运行脚本时,我得到以下输出:
Select a fruit:
./fruit_selection.sh: line 14: $item_nothing[0]: command not found
./fruit_selection.sh: line 15: $item_nothing[1]: command not found
./fruit_selection.sh: line 14: $item_banana[0]: command not found
./fruit_selection.sh: line 15: $item_banana[1]: command not found
./fruit_selection.sh: line 14: $item_orange[0]: command not found
./fruit_selection.sh: line 15: $item_orange[1]: command not found
我不知道我做错了什么。您有解决方案来实现我所描述的目的吗?另外,如果您有比我开始做的更好的方法,请毫不犹豫地提出建议。
编辑:for循环中的解决方案如下
#!/usr/bin/env bash
item_nothing=("0" "Nothing" "")
item_banana=("1" "A banana" "select_banana.sh")
item_orange=("2" "An orange" "select_orange.sh")
items=(
"item_nothing"
"item_banana"
"item_orange"
)
printf "Select a fruit:\n"
for item in "${items[@]}"; do
var_0=$item[0]
var_1=$item[1]
printf " ${!var_0} "
printf "${!var_1}\n"
# var_3=$item[3]
# do something with this later "${!var_3}\n"
done
答案1
我会为您拥有的每条信息创建一个数组,而不是每个项目。如果你愿意的话,可以是列,而不是行。另外,如果您愿意从零开始对它们进行编号,则无需显式存储索引。
这将呈现数组中一些水果名称的使用,并基于其他数组中的较短代码或命令名称进行工作。
# names and values, the order must be the same in every array
item_names=(Nothing "A banana" "An orange") # displayed to user
item_codes=(NIL BAN ORA) # for internal use
item_funcs=('' do_banana '') # names of functions called
# special function for bananas
do_banana() {
echo "Banana function called"
}
# present choices and read entry
for (( i=0 ; i < ${#item_names[@]} ; i++ )) {
printf "%2d %s\n" "$i" "${item_names[i]}"
}
read num
# XXX: verify that 'num' contains a number and is in the range...
printf "You chose the fruit with code '%s'\n" "${item_codes[num]}"
# if there's a function connected to this fruit, call it
if [ "${item_funcs[num]}" ]; then
"${item_funcs[num]}"
fi
# or do something based on the chosen value
case "${item_codes[num]}" in
NIL) echo "do something for nothing" ;;
BAN) echo "do something for banana" ;;
ORA) echo "do something for orange" ;;
esac
如果您输入1
,它将打印您选择的内容BAN
并运行语句的相应分支case
,并调用香蕉函数。您需要确保num
仅包含一个数字并检查它是否在现有项目的范围内。
请注意,存储带有这样的参数的完整命令并不简单,因为要正确存储它们,每个命令都需要一个数组。如果您需要这样做,最好只使用该case
语句。看:我们如何运行存储在变量中的命令?