Simple BASH menus

How to make simple menus in Linux

By Floor Anthoni (July 2007) 
www.seafriends.org.nz/linux/menus.htm
All debian-based Linux distros provide menus to launch applications from, but in order to harness the power of operating system functions and make these available to other operators, simple menus are needed. This chapter shows a very simple menu structure that can be maintained by amateurs.
.

 back to contents page  Seafriends home page   feedback   Rev:070706,


the basic menu

A menu is an executable text file, a script, and we'll use the powerful bash (Bourne Again Shell) to harness the power of the Linux operating system. Bash is a command-line interpreter that can interpret computer language elements like  if . . .then . . .else  and while . . . do . . . done  and in fact enough to be a programming language in itself. For those familiar with DOS, bash has elements of the batch commands. Note that all Linux distros have bash, so these menus should work on all distros.
Usually a menu is just a traffic agent directing the user to an application, but the menus discussed here are more powerful because they contain the applications (the programs) as well. Here is part of a menu to show what is involved. The parts in blue are execution commands whereas the rest is the menu proper.
 
#!/bin/bash
# simple menu to do various functions

while [ answer != "0" ] 
do
clear
echo "Select from the following functions"
echo"  0    exit"
echo"  1    set wacom pen"
echo"  2    remove System Volume Information folders"
echo"  3    EPSON printer clean head"
echo"  4    exit"
echo"  A    Backup E: zipped to G:"
read -p " ?" answer
    case $answer in
       0) break ;;
       1) echo "wacom setup"
       xsetwacom set stylus clickforce 15
       xsetwacom set stylus button3 1
       xsetwacom set stylus button2 3
       ;;
       2) rm -rf /disks/D/"System Volume Information"
       rm -rf/disks/E/"System Volume Information"
       rm -rf /disks/F/"System Volume Information"
       rm -rf /disks/G/"System Volume Information"
       ;;
       3) escputil -q --raw-device=/dev/usb/lp1 -i
       ;;
       4) break ;;
       A|a) echo "enter zip archive name (eyymmdd)"
       read name
       cd /disks/E/
       zip -r /disks/G/$name.zip *
       cd ~/
       ;;
       *) break ;;
   esac 
   echo "press RETURN for menu"
   read key
done
exit 0

Now, that looks like a whole lot of gobbledigook, but in your smart editor, it looks a whole lot better with all those colours. In other words, the editor (kedit) knows what the syntax of this script is. Here is how it works:

The main loop while . . . do . . . done waits for an answer and dependent on that answer, branches out with the case ... in .... esac construct. There are break commands to break out of the while .. do loop and when done, the script exits with error code 0 (=OK), cleaning up the window. There is also a very simple dialogue that asks for part of a file name for a zip file.
The three examples are: 1= setting up the pen tablet,  2= removing folders,  3= a printer command to display remaining ink levels, A= a zip backup of our entire own work on drive E.

As you can see, these commands extend the utility of your work, and allow anyone to do tricky things without any risk or advanced knowledge. Should you wish to know all details, ask the manual (man) for xsetwacom, rm, escputil and zip, but for understanding the menu, this is not necessary.

The program reads as follows: while the answer is not 0, loop around, first clearing the screen, then printing (echo) the menu and waiting for a key stroke and enter/return. The operator could have typed a whole word, even a whole line, but we expect a single letter, which is stored in the string variable answer.
In case the $answer string is 0, 1 ,2 ,3 ,4 ,A or a, do what is in between ) and ;; and once done, go to esac (case spelled back to front). Here the operator is prompted to press the return key first before the screen is wiped and the menu re-displayed. The key (or word or line) is read to the key string which we don't use. The break command breaks out of the do-loop and goes to done.

The purist will notice that the do loop can be set up to never finish: while true do ...  because a 0 answer is tested for in the case branch and breaks out anyway.

In option A or a (A|a), the program briefs to enter the zip archive name, read to name. The program changes directory (cd) to the own work disk E and issues the zip command recursively (-r) for all folders, and output to the G drive with a filename $name just entered, followed by .zip file extension. Once done, it thoughtfully changes the directory back to my_home ~/.
* is the code for anything not a letter or a digit, which in our case breaks out of the loop.

One could not make a menu simpler than this, could we? Save it to ~/ with filename submenu1, because most likely you will need a main menu as well in due course.


activating the menu

Your text file becomes a script by its first line #!/bin/bash which says that the program bash in /bin should execute this script, and that is the bash shell. However, the script must also be made executable, and this is most easily done with the Xandros File Manager (XFM). 
Right-click on ~/submenu1 and select properties. It tells you that this is a Bourne script text executable. Click on the permissions tab and tick the execute checkboxes for owner, group and others. Here you specify who can use and modify (write) this menu. In the group drop-down list you can indeed be very specific. Click OK. The script is now executable.

At this point you can double-click on the submenu1 file, and it will run the menu. Now we need to put it in the menu tree.

For Xandros this means using the menu editor: launch> applications> system> menu editor.
Navigate to the menu folder where you want your menu placed. Click File> new item and enter the specifics. The important thing is command: ~/submenu1 and to tick 'Run in terminal' which turns the console on. The path is not important here.
As a refinement, we'll try to find a suitable icon: click on the icon and find a suitable one, like alevt. Exit the menu editor to activate the changes.

Once the icon is in the menu tree, you can drag it onto the desktop. If you install a main menu, you may need to change the menu tree and icon on the desktop.


the main menu

Once you find a single menu becoming cumbersome, you may wish to hang the submenus off a main menu, and then the possibilities become unlimited, so here it is.
#!/bin/bash
# main menu 

while [ answer != "0" ] 
do
clear
echo "Select a submenu"
echo "  0  exit"
echo "  1  utilities: wacom, epson, clear SVI, rsync backups"
echo "  2  photos: remove headers with JHEAD"
echo "  3  "
read -p " ?" answer
    case $answer in
        0) break ;;
        1) bash ~/submenu1
        ;;
        2) bash ~/submenu2
        ;;
        3) 
        ;;
        *) ;;
    esac 
done
exit 0

Note that this menu does not need to ask 'press return for menu' because that is done in the submenus. It can't be simpler than this.


.