I want to implement a selection menu in bash (version 3.2 on macOS) which would output something like this:
Select a fruit:
0 Nothing
1 A banana
2 An orange
When the user will choose an item, I want to be able to run an associated bash script. For this, I would need something like a 2-dimension array but if I am not wrong it does not exist in bash. I thought about using several arrays in a main array. Then I would use a loop to display the menu to the user:
#!/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
When I run my script I get the following output:
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
I have no idea what I am doing wrong. Would you have a solution to achieve what I describded? Also, if you have a better way than what I started to do, do not hesitate to suggest it.
EDIT: solution below in the for loop
#!/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
select
statement I think? this looks like a canonical use-case for that – steeldriver Jul 05 '20 at 14:49var=$item[1]; printf "${!var}"
I get exactly what I want: the second element of my sub-array. However, may I ask you how to use a single statement instead of using a variable before the printf? I triedprintf "${!$($item[1])}"
but I got this error: ./fruit_selection.sh: line 20: ${!$($item[1])}: bad substitution. – Mat.R Jul 05 '20 at 18:47items=(Nothing 'A banana' 'An orange')
thenselect fruit in "${items[@]}"; do case $fruit in "Nothing") break;; *) echo "You selected: $fruit";; esac; done
- fill in thecase...esac
as you wish – steeldriver Jul 05 '20 at 19:08case
statement - sorry if that wasn't clear – steeldriver Jul 05 '20 at 22:03