Simple Menu with Bash’s Select Command

The Problem

Sometimes, I need a simple menu in bash, but I don’t want to spend a good deal of time coding for one.

The Solution

Bash has a built-in command called select which gets the job done. To demonstrate this command, I am going to write a short bash script. This script lists all the files in the current directory, then prompts the user to make a choice. If the choice is valid, it invokes the editor on the file. It will ignore any invalid choice. Below is the source for that script:

#!/bin/sh
# Displays a list of files in current directory and prompt for which
# file to edit

# Set the prompt for the select command
PS3="Type a number or 'q' to quit: "

# Create a list of files to display
fileList=$(find . -maxdepth 1 -type f)

# Show a menu and ask for input. If the user entered a valid choice,
# then invoke the editor on that file
select fileName in $fileList; do
	if [ -n "$fileName" ]; then
		vim ${fileName}
	fi
	break
done

Explanation

Line 6 – By default the select commmand uses ‘#?’ as a menu prompt. If the variable PS3 is defined, it will use that variable instead.

Line 9 – The find command retrieves a list of files in the current directory. The script then stores the result in the variable fileList

Line 13 to 18 – The select .. do .. done command displays a menu using $fileList as a list of items.

Line 14 to 16 – This block of code check if the user’s choice was valid and invoke the editor accordingly

Line 17 – The select command acts like an endless loop unless a break command is encountered

Sample Run

Below is a sample run

	$ edit_files.sh
	1) ./arguments		        
	2) ./data		            
	3) ./for_example	        
	4) ./getopt_function.sh	   
	5) ./getopt_homemade.sh	   
	6) ./getopt_tryout
	Type a number or 'q' to quit: 3

The Hack

If you are reading this far, I hope you detected my hack (hint, look at the PS3 prompt). By experimenting with select, I found out that if the user entered an invalid choice (i.e. a letter ‘q’ instead of an integer) then select will set the control variable ($fileName in this case) to empty. Taking advantage of this feature (or bug?), I designed the prompt and check for non-empty variable (line 14-16) before invoking the editor.

Conclusion

The select command is easy to use, but it save the script writers from the tedious job of displaying the menu, the prompt, then ask for the user’s input. The only caveat programmers need to watch out for is the lack of input validation so be sure to check your control variable before using it.

7 thoughts on “Simple Menu with Bash’s Select Command

  1. Pingback: My version of internet radio on the RPi | My Blog

  2. Pingback: LastFm plays on my headless RPi wifi radio | My Blog

  3. Pingback: Improvements to my RPi radio | My Blog

  4. lovelybacon

    thank you kind sir for this excellent guide. I used it to make a conky switch script

    #!/bin/sh
    # Displays a list of files in current directory and prompt for which
    # file to edit

    # Set the prompt for the select command
    PS3=”Type a number or ‘q’ to quit: ”

    # Create a list of files to display
    fileList=$(find /home/zx/conky -name conkyrc -type f)

    # Show a menu and ask for input. If the user entered a valid choice,
    # then invoke the editor on that file
    select fileName in $fileList; do
    if [ -n “$fileName” ]; then
    cp ${fileName} /home/zx/.conkyrc
    fi
    break
    done

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s