Create a select menu with smenu

Not Spoiled for Choice

© Lead Image © acik,

© Lead Image © acik,

Article from Issue 205/2017

The smenu tool reduces the effort of creating shell menus to one line, with numerous options for a wide range of design alternatives.

If you program for the shell frequently, sooner or later you will have to create a select menu, which usually requires several lines of code – unless you use smenu. Smenu reduces the menu's script to a single line. A number of parameters allow you to adapt the design and to simplify your work a little.

The source code for smenu is available on its project page [1], which contains installation instructions, as well as some useful tips. The smenu wiki [2] contains links to two YouTube videos that demonstrate the practical use of the program. The README file provides a structured overview of smenu's options [1].

Basic Function

In smenu's simplest form, a command's output is passed via pipe to the smenu command. For example, <command> | smenu displays a selection on a single line. To create a line-by-line menu, use <command> | smenu -c (Figure 1).

Figure 1: Pipe command output to smenu and leave it to the program to prepare the output in the form of a single-line menu.

For a freely defined menu, transfer the selection options using the echo command. However, the examples in Figure 2 only show the most rudimentary form: It doesn't make sense to use the tool without variables.

Figure 2: If you want to enter the selection options with your own text, use the echo command.

1 lists the most important call options for smenu. Press Enter to select a menu option, and press Q to exit the menu without selecting. To search within the selection, use the forward slash (/) in the open menu and then enter the search term.

When the search completes, the cursor stops at the first hit, and the background appears blue instead of black. If you wait seven seconds, the software reverts back and waits for your next input. Typically, the selection results from the data obtained via the pipe.

Script Use

To use the result of the selection, apply command substitution, as shown in Listing 1, line 1 (current syntax) and line 2 (obsolete syntax). Listing 2 and Listing 3 show two functional examples, and Figure 3 shows their usage.

Listing 1

Command Substitution


Listing 2

A Selection with Explanations

a=$(echo "1 first \n 2 second \n 3 third \n" | smenu -c)
echo "input value: $a"

Listing 3

Selecting a File

b=$(ls *.txt | smenu -c)
echo "Selected file: $b"
Figure 3: Listings 2 and 3 show simple scripts that demonstrate how you can easily create a menu for your software with smenu.

Table 1

smenu Options





Column mode

-m "<Text>"


Listing 4


Limit lines in selection

Listing 4


Center menu


Delete menu according to selection on the screen


Selection with several columns

Listing 5


Selection with multiple columns at full terminal width

Together with -t

-T <Field Separator>

Allow multiple selections

Listing 6

-e <Expression>

Exclude the transferred string from the selection

Listing 7

-i <Expression>

Only allow designated strings to select

Listing 8

Listing 4

Specifying the Heading

a=$(ls -1 *.txt | smenu -n3 -c -m "Select file:")
echo "Selected file: $a"

Listing 5

The -t Option

a=$(ls -1 *.txt | smenu -n3 -c -m "Select file:" -t2)
echo "Selected file: $a"

Listing 6

Using a Colon as a Field Separator

a=$(ls -1 *.txt | smenu -n5 -T: -c -m "Select file(s) (mark with [T]):")
echo "Selected file(s): $a"

Listing 7

The -e Option

a=$(ls -1 | smenu -n5 -c  -e [m][4] -m "Select file: ")
echo "Selected file: $a"

Listing 8

The -i Option

a=$(ls -1 | smenu -n5 -c  -i [t][x][t] -m "Select file: ")
echo "Selected file: $a"

Listing 2 demonstrates how to establish a selection with explanations. The end-of-line symbol (newline), which you represent with an escape sequence (\n), serves as a separator between the entries. Within an entry, the space serves as a separator between fields. The result adopted in the variable is the value from the first column. Smenu only inverts the current value of the variable on the screen, not the full line.

Listing 3 shows just how easily users can select a file interactively.


Figure 4 shows a small menu, which already has some additional features. If the list of entries reaches a certain number of lines, a green scrollbar appears.

Figure 4: The green scrollbar shows that there are more items from which to choose.

If you limit the number of visible lines to three with -n3, the bar appears as soon as the length of the list exceeds this value. Use the -m "<text>" option to specify the heading. Listing 4 shows the corresponding code.

Look at the scrollbar in Figure 4 more closely: If you reach the start or the end of the selection, the arrow symbol appears. The arrows indicate more entries in the respective directions.

If you need a selection with multiple columns, type the number of columns using the -t option (Listing 5). Figure 5 shows the result on the terminal screen. If you want to expand the line content to the terminal's full width, use the -w option.

Figure 5: If necessary, distribute the data for the selection to multiple columns.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • Scripted Printing

    A few commands and some simple shell scripts make it easier to manage your printer so that you can access print functions quickly and automate recurring tasks.

  • Time Machines

    Command-line aficionados do not have to forgo calendars and appointment reminders. The shell offers many tools for user-friendly handling of date definitions in scripts.

  • Metadata in the Shell

    Armed with the right shell commands, you can quickly identify and evaluate file and directory metadata.

  • FOSSPicks

    Graham explores GnuCash 3, Kawaii-Player 3.3.1, tig, HandBrake 1.1.0, GameMode, XLEngine, and more!

  • Workspace: Text Expander

    A couple of utilities and a dash of Bash scripting are all you need to roll out a simple yet flexible text expander.

comments powered by Disqus
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters

Support Our Work

Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.

Learn More