Adding a simple GUI to the console in Linux

There's probably a lot of scenarios in general Unix administration wherein you'd like to create a simple GUI for people to do tasks. This way you can give non-technical people the ability to do things like check printer queues or do add users or whatever. Obviously, writing a shell script with regular text output is one option, but the 'dialog' tool is another.

I recently ended up needing to make a simple dialog system for users. Most shops end up having mixed environments where there are Windows and Linux boxes in the same racks. Occasionally, a Windows admin will hop on the KVM on a host with a black screen, and hit Control-Alt-Delete, because that doesn't really do anything in Windows. Unfortunately, in Red Hat Enterprise Linux, at least, this ends up restarting the box, which obviously isn't the best thing in production environments.

So, I wrote a shell script using dialog to create a nice, flashy console GUI so that when someone hits control-alt-delete they're presented with options. In my workplace, we have server room 'operators' that man the server room 24x7. They're generally not as Unix oriented, so I added some options in my script to allow some simple diagnostics. The script is really really simple, so I'm not going to post it here, just some quick things I came across while using dialog.

Here's some quick notes on using dialog:

It's VERY picky as to how you do things. I don't remember specifics, just that having spaces in the wrong place occasionally made it not work properly.

When writing your script, remember people may not be using as large of a terminal as you are, so test it out on default terminal sizes to make sure it works there.

When creating anything that utilizes a menu or user input in dialog, output is sent to STDERR. So, generally, you'd do something like:

dialog ... 2>/tmp/somefile

This presents two things to think about, first, creating a unique 'somefile', but also remembering to remove that file. Here's one way that I've done this (I added the line numbers to show it's a single script):

1. #!/bin/bash
2. hosttmp="/tmp/.$(basename $0).${RANDOM}.${RANDOM}"
3. dialog --inputbox "Enter DNS name or IP address to ping:" 8 40 2>$hosttmp
4. hostping=$(cat ${hosttmp})

This grabs the content and dumps it into a file. Next, do something with the content, in this example, ping a host.

Note: Some Linux distributions have the command 'tempfile' which returns a unique filename in /tmp. I found that not all systems have this command, so I did it in pure bash as shown above.

5. dialog --title "Pinging ${host}..." --msgbox "$(ping -c3 ${host})" 20 75
6. rm ${pinghost}

So, I've created a simple dialog for the user, asked for input, wrote the input to a given file, then displayed the output to the user.

Above, I used the --msgbox widget to display the output of the ping command. If you're going to display a large amount of output, this widget is very slow. The --textbox widget is much much faster displaying large amounts of content. The textbox widget, however, requires output from a file, creating requiring two files for widget operation, unless you use the same file twice as I do below:

findproc="/tmp/.$(basename $0).${RANDOM}.${RANDOM}"
dialog --inputbox "Enter name of process to find:" 8 40 2>$findproc
process=$(cat ${findproc})
`ps -ef | grep -v grep | grep ${process} > ${findproc}`
dialog --title "Finding ${process} in the process table" --textbox ${findproc} 20 75
rm ${findproc}

Finally, how to make the Control-Alt-Delete menu appear? It's pretty simple, actually, just edit /etc/inittab (On Red Hat systems, anyways),and modify the following:

# Trap CTRL-ALT-DELETE
ca::ctrlaltdel:/usr/local/bin/my_neat_menu

I found that this works well if not logged into the current tty, but doesn't work so hot if you're logged in. I haven't figured out how to fix that just yet, since the chvt command doesn't seem to work quite like I'd like it to.