'Linux script select menu
I need to create a select menu with six options using the select loop and the case instruction BUT NOT THE ECHO COMMAND FOR THE MENU OPTION and they have to display like this:
1) opt1
2) opt2
3) opt3
4) opt4
5) opt5
6) opt6
And not like:
1) opt1 3) opt3 5) opt5
2) opt2 4) opt4 6) opt6
So far I have this code, but the problem is with the display, with 5 options it displays vertically, but with 6 it displays side by side:
#! /bin/sh
PS3="Enter your choice :"
select choice in "opt1" "opt2" "opt3" "opt4" "opt5" "Exit"; do
case $REPLY in
1) echo "$choice";;
2) echo "$choice";;
3) echo "$choice";;
4) echo "$choice";;
5) echo "$choice";;
6) echo "see you next time";break;;
*) echo "Wrong choice!";;
esac
done
Solution 1:[1]
Adjusting the COLUMNS variable helps to limit the number of columns in the menu. I typically do (in a script):
COLUMNS=1
select ...
when I want one column all the time.
To be precise, COLUMNS=1 means that your TERMINAL is ONE CHARACTER wide. The select command then has no choice but to then print ONE COLUMN of menu items.
To be REALLY accurate, you could
- find the length of the longest item (itemLen)
THIS IS INCORRECT=> 2. find the number of items and mod by ten to get the max number of digits (numberLen) <=
- find the total number of items "n" and calculate int(log10(n))+1 (numberLen)
- COLUMNS=((itemLen + numberLen = 2))
where the '2' is for the paren and space between the menu item number and the item. But this is not necessary.
Solution 2:[2]
Try something like this:
menu()
{
cat <<EOF
1) opt1
2) opt2
3) opt3
4) opt4
5) opt5
6) opt6
q) quit
EOF
echo -n "make your choice > <^H^H"
read -n 1 foo
echo
case "$foo" in
1|opt1) echo "opt1" ;;
2|opt2) echo "opt2" ;;
3|opt3) echo "opt3" ;;
4|opt4) echo "opt4" ;;
5|opt5) echo "opt5" ;;
6|opt6) echo "opt6" ;;
q|quit) echo "bye bye!" ;;
esac
}
The ^Hs stand for the ASCII sequence 0x08 or BS (backspace).
(In vim you can type this with CTRL+v and then CTRL+h)
Solution 3:[3]
I've got the same problem. I didn't understand how exactly select uses LINES and COLUMNS (see "Shell Variables" in the bash man page), but setting COLUMNS to 1 (some small value indeed) helped me.
Solution 4:[4]
You can use the select builtin, if available:
#!/bin/bash
select o in opt{1..6}; do
case "${o}" in
opt[1-6])
break
;;
*)
echo "Invalid choice '${REPLY}', please pick one of the above"
;;
esac
done
echo "You picked: ${o}"
Example run:
$ ./t.sh
1) opt1
2) opt2
3) opt3
4) opt4
5) opt5
6) opt6
#? 9
Invalid choice '9', please pick one of the above
#? asdf
Invalid choice 'asdf', please pick one of the above
#? 1
You picked: opt1
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Uroc327 |
| Solution 3 | |
| Solution 4 | Adrian Frühwirth |
