Views:
711
Votes: 3
✅ Solution
Tags:
command-line
bash
scripts
menu
Link:
🔍 See Original Question on Ask Ubuntu ⧉ 🔗
URL:
https://askubuntu.com/q/832766
Title:
Can line draw characters (or colors) be added to a Bash file list menu?
ID:
/2016/10/03/Can-line-draw-characters-_or-colors_-be-added-to-a-Bash-file-list-menu_
Created:
October 3, 2016
Edited: April 13, 2017
Upload:
April 8, 2024
Layout: post
TOC:
false
Navigation: true
Copy to clipboard: false
I created the world’s ugliest menu using the first Linux tool I’m learning, BASH.
What the Menu Looks Like
The following /usr/local/bin/bell/sounds were found
1) /usr/local/bin/bell/sounds/Amsterdam.ogg
2) /usr/local/bin/bell/sounds/bell.ogg
3) /usr/local/bin/bell/sounds/Blip.ogg
4) /usr/local/bin/bell/sounds/default.ogg
5) /usr/local/bin/bell/sounds/Mallet.ogg
6) /usr/local/bin/bell/sounds/message.ogg
7) /usr/local/bin/bell/sounds/Positive.ogg
8) /usr/local/bin/bell/sounds/Rhodes.ogg
9) /usr/local/bin/bell/sounds/Slick.ogg
'a' to hear to all files, use number to hear a single file,
'u' to update last single file heard as new default, or 'q' to quit:
The Code
#! /bin/bash
# NAME: bell-select-menu
# PATH: /usr/local/bin
# DESC: Present menu of bell sounds to listen to all, listen to one and update default.
# CALL: bell-select-menu
# DATE: Created Oct 1, 2016.
echo "The following /usr/local/bin/bell/sounds were found"
# set the prompt used by select, replacing "#?"
PS3="'a' to hear to all files, use number to hear a single file,
'u' to update last single file heard as new default, or 'q' to quit: "
lastfile="none"
# allow the user to choose a file
select filename in /usr/local/bin/bell/sounds/*.ogg
do
# leave the loop if the user types 'q'
if [[ "$REPLY" == q ]]; then break; fi
# play all if the user types 'a'
if [[ "$REPLY" == a ]]
then
playall-bells
continue
fi
# update last file name as new default if the user types 'u'
if [[ "$REPLY" == u ]]
then
if [[ "$lastfile" == none ]]
then
echo "No file was selected."
break
fi
echo "$lastfile selected"
cp $lastfile /usr/local/bin/bell/sounds/default.ogg
load-default-bell
break
fi
# complain if no file was selected, and loop to ask again
if [[ "$filename" == "" ]]
then
echo "'$REPLY' is not a valid number"
continue
else
lastfile="$filename"
fi
# listen to the selected file
ogg123 "$filename"
# loop back to ask for another
continue
done
I based the code on an answer from AskUbuntu: Create bash menu based on file list (map files to numbers). The menu scrolls off the screen as user options are repeatedly entered though, so the loop needs to be adjusted.
The world’s ugliest menu is automatically generated so I can’t hard code ASCII line draw characters on the left and right sides. Would I need to call a program to reformat the menu?
The bulk of the menu is generated by a single bash command:
select filename in /usr/local/bin/bell/sounds/*.ogg
I read the Bash manual on the select
statement but don’t see any options. Is there a program that can be called to massage the screen?
The closest thing I’ve found is called tput
described here: linuxcommand.org/lc3_adv_tput but I’m not sure if it’s practical for this problem.
Thanks in advance :)
PS This menu is one of the tools to get rid of annoying loud speaker beep in Terminal and gedit
as described here: Turn off Motherboard/PC Speaker "beep" in Ubuntu 16.04 regression
Edit - Incorporating Accepted Answer
Many thanks to wjandrea for posting code to clean up the menu. Prior to the accepted answer I had added code for color in echo
strings and PS3 (prompt). I had also put in a loop to redraw the menu to prevent it scrolling off the screen. I also put in a reset
to clear the screen before repainting. This prevents more and old copy (sometimes truncated) and new copy of the menu appearing at the same time.
New Menu Look
The colors aren’t accurately represented when copying from terminal text output and pasting into AskUbuntu.
===== Sound Files for Bell in /usr/local/bin/bell/sounds/ ====
1) Amsterdam.ogg 4) default.ogg 7) Positive.ogg
2) bell.ogg 5) Mallet.ogg 8) Rhodes.ogg
3) Blip.ogg 6) message.ogg 9) Slick.ogg
=========================== Options ==========================
'a' to hear to all files, use number to hear a single file,
'u' update last number heard as new bell default, 'q' to quit:
This is all that appears on the screen now. There is no $ sudo bell-menu
call statement visible. No other history of previous commands typed visible.
A screen shot shows the colors accurately and you can see the screen has been programmatically blanked out:
New Menu Code
#! /bin/bash
# NAME: bell-menu
# PATH: /usr/local/bin
# DESC: Present menu of bell sounds to listen to all, listen to one and update default.
# CALL: sudo bell-menu
# DATE: Created Oct 6, 2016.
# set the prompt used by select, replacing "#?"
PS3="
=========================== Options ==========================
$(tput setaf 2)'$(tput setaf 7)a$(tput setaf 2)' to hear to all files, use $(tput setaf 7)number$(tput setaf 2) to hear a single file,
'$(tput setaf 7)u$(tput setaf 2)' update last number heard as new bell default, '$(tput setaf 7)q$(tput setaf 2)' to quit: $(tput setaf 7)"
cd /usr/local/bin/bell/sounds/
# Prepare variables for loops
lastfile="none"
wend="n"
while true; do
tput reset # Clear screen so multiple menu calls can't be seen.
echo
echo -e "===== \e[46m Sound Files for Bell in /usr/local/bin/bell/sounds/ \e[0m ===="
echo
# allow the user to choose a file
select soundfile in *.ogg; do
case "$REPLY" in
q) # leave the loop if the user types 'q'
wend="y" # end while loop
break # end do loop
;;
a) # play all if the user types 'a'
playall-bells
break # end do loop
;;
u) # update last file name as new default if the user types 'u'
if [[ "$lastfile" == none ]]; then
echo "No file has been heard to update default. Listen first!"
continue # do loop repeat
fi
echo "$lastfile selected"
cp "$lastfile" default.ogg
load-default-bell
wend="y" # end while loop
break # end do loop
;;
esac
# complain if no file was selected, and loop to ask again
if [[ "$soundfile" == "" ]]; then
echo "$REPLY: not a valid selection."
continue # repeat do loop
else
lastfile="$soundfile"
fi
# listen to the selected file
canberra-gtk-play --file="$soundfile"
# loop back to ask for another
break
done
if [[ "$wend" == "y" ]]; then break; fi
done
The menu was renamed from bell-select-menu
to bell-menu
. Because it resides in /usr/local/bin
it needs to be called with sudo bell-menu
and the comments were updated to reflect this fact.
With a little work the world’s ugliest menu and now become and acceptable looking (but not beautiful) menu.