HowTo: Use tput in a shell data entry system - Part 1

Learning to use Linux at Home and WorkWelcome to my ongoing series of HowTo articles designed to help Linux newbies get comfortable with Linux. Before trying any of these HowTos, take a few minutes to study the prerequisites so you can hit the ground running.--Stomfi

This HowTo describes a shell terminal based data entry system using "tput" and other cursor and screen attribute commands to create a useful and sophisticated interface without using a GUI. A basic inwards/outwards goods system is used as the platform to show these and other shell features including the use of functions. The system is developed in a top down fashion starting with the basics and reappraising the design, adding new features identified, in an ordered and prioritised fashion.

I have spent a lot of time showing you how to use a Runtime Revolution GUI interface to create data entry systems, but for these exercises I am going to show you how "tput" and other shell tools can be used to create a similar system in a shell terminal.

There are many instances when a shell terminal without a GUI window manger running is sufficient to do the job at hand, saving a lot of money on resource costs. A system like the one I'm going to describe can be run on an old P1 or even a 486, with a very light Linux non-GUI distro. One can use the shell script as a front end to a back end on a server, and being Linux, several serial based terminals can be connected to one PC, saving even more resources.

The tput shell command uses the terminfo database to make the values of terminal dependent capabilities available to the shell. The man page for terminfo(5), which you can read with the command,

man 5 terminfo

lists all the capabilities available. The /etc/terminfo database lists those that the terminal command strings are known for listed terminal types.

We are going to use a simple subset of all the commands, sufficient to achieve our purposes.

The examples in "man tput" gives you a good idea how tput can be used. You will find that some of the tput commands work differently in a terminal invoked inside an X window manager than in a virtual terminal invoked by say "CTRL-ALT-F2". This is because the X terminal is of type "xterm" and the virtual terminal is of type "linux"

setb 3 which sets the screen background to the colour defined as the number 3. There are 8 colours.
clear which clears the screen effectively painting the new colour all over it.
cup 8 13 which puts the cursor at row 8 column 13 (which in this case is after the "select" message).
el which deletes to the end of the current line. (Deleting the previous selection, if any).
cup 15 20 which puts the cursor to line 15 row 20.
el which deletes to the end of the current line.
reset which resets the terminal to its previous state.
clear which in this case repaints the screen to its original colour.

It may be better to use "reset" which is a link to the "tset" command, rather than the "tput" version if funny things happen to your terminal. (I have found that "mc" doesn't like me using "tput reset" in a virtual terminal.)

The setb command works fine:

You can also use "setf" to change the foreground or text colour. The other tput commands we will use will "bold", "blink", "hide" and "show" text depending on what we are doing.

To really show off the capabilities of terminal based Linux, we will create the type of system where terminal functions are more productive. One that comes readily to mind is inwards and outwards goods for a small business, using a central server and inexpensive refurbished PCs, that can be recycled and replaced if they go wrong. These are something that you can pay $100 for a 20 to 50 PC lot at an auction. I find that P1s with 32MB and 1.3GB drives are easy to come by. You can install something like Damn Small Linux on this type of system using runlevel 3 which gives you a fully networked console based system. Then you can get a GUI interface by using startx if you need it. I find it best to install 3 Com 10/100 PCI Ethernet cards as these are well supported by all Linux distros.

This is a top down of the initial plan of the system. We shall add more to this picture as we discover more functions that are needed. It is a good idea to plan your system like this, prove this bit works, before getting more complex. This way you will minimise mistakes, and always know what you are trying to achieve.

Adjust is used if the entry is a mistake, or if a stock take finds discrepancies. Doing it this way is good practice as all entries and adjustments can be used as objective evidence.

Post is where the data is sent for keeping. This can be files on the local PC or on a networked file server.

Using the testmenu.sh example, we can copy and modify it and produce goods.sh, inwards.sh, and outwards.sh which look like this with a few variations.

Pretty psychedelic, eh!

The goods.sh script is different from the other two, as it has to exit back to the shell.

The exec replaces the current shell with the new one. This minimises memory usage in a small system.

I have made the point where I paint the screen of these two menus different on purpose so that you can decide which is more appropriate.

I'm going to use functions in the entry and adjust shell scripts, something I promised to introduce to you. The screen painting function is an obvious choice for this application as there is a lot of repetition.

Initially we'll be using simple shell entry with tput to move the cursor around.

As we progress we shall use some more sophisticated tools to retrofit things like selection lists.

This is the initial inwards goods data entry screen:

The date gets set automagically. Each field has to be filled before the next can be entered. After the last entry the message whether to post the entry appears. If y or Y response the entry is posted to a file.

That was very straight forward. You could probably see that the dopost function wasn't necessary as it is only used once and could have been written where it was called.

We can get more sophistication by trapping the user in this screen until the correct responses are given, making sure that arrow keys and the like do not mess up the screen, and allowing the user to re edit the entries after a negative response to the OK to Post question, but at this stage we are just proving that the concept will work, so will leave these additions for later.

An important entry detail that I have left out of the inwards screen is the type of inwards goods. Whether it is stock, or whether returned outwards goods. You can insert all the lines to cover this information.

The outwards goods script will be pretty similar and you should be able to work out something adequate by copying and modifying the ingoods.sh script.

Here is the dopost function from that script to give you a clue to the necessary changes. Don't forget to change the last line exec to point to the outwards.sh script.

In a practical goods system, one of the biggest problems is: Where did it go after it was received? Connecting a label printer to our system, which prints a sticky destination label for immediate attachment to the goods would minimise location errors and identify wrongly placed items. If you can think of a way that is just as effective, let me know and I'll include it. I expect RFID will eventually alleviate the problem, but small business needs a cheap solution.

Now we come to the adjustment scripts. These scripts read and select the relevant line from the data file, display the data and allow it to be edited. The result is posted as a new record for objective evidence of the modification.

You can immediately see that we have a problem with this. How do we know how the modified entry relates to the other one, and which one does it relate to anyway?

I'm going to leave you to think about it till next time. I wonder if we come up with a similar solution.