Novell Home

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

Novell Cool Solutions: Feature
By Stomfi

Digg This - Slashdot This

Posted: 8 Sep 2005
 

StomfiLearning to use Linux at Home and Work
Welcome 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
In the last article, we started the development process for a goods system using a text based terminal rather than a GUI. We developed the screens and scripts for the main menu, the Inwards and Outwards goods menus, and the inwards and outwards goods data entry and record posting screens according to this design.

You may remember that one of the things we needed to stop happening in the terminal was to prevent key sequences like CTRL-C having any effect.

This is done with a shell command called "trap". The command syntax is: trap action signals

In our scripts we don't want any action, but we need to put the null string "" in there which does nothing, as no given action sets the signals to their default action, not what we are trying to achieve.

If you insert this line at the start of each script after the comments, things like CTRL-C will be trapped. You can look up the man page for a lot more detail about this useful command.

trap "" 2 3 9 15

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?

My solution is to save the changed data in the main file with the current date, and the original in a history file. In this simple fashion, all the objective evidence of changes are saved, and it's up to the stock reconciler to follow the trail correctly.

The adjustment screen asks for a valid docket number and if it doesn't get one prints a quit message. If it does it prints the record and waits for changes or the enter key until all are done. On response from the user, the old record is saved in the history and the new record saved in the current records.

This is a picture of the first question:

Here is the adjustment record being changed:

Here is the script. The other one is the same except for the Customer field references and the output files.

#!/bin/bash

#inadjust.sh

#select and adjust an existing record by posting a new record

#If the records don't use a unique time key, which field would be selected

#in the case of text data. A time stamp could be saved as part of the

#record, but if this is to happen, it is just as easy to make the new record

#the one which is "right"and save the old data in an adjustments history file,

#replacing it in the active records with the new data.

#

#Trap signals

trap "" 2 3 9 15

#function to paint all fields onto the screen

function scrnpaint()

{

   tput clear

   echo ""

   echo ""

   echo " INWARDS GOODS ADJUSTMENT"

   echo ""

   echo ""

   echo " Entry Date: $EDATE"

   echo " Docket Number: $DOCNUM"

   echo " Supplier Code: $SUPPCODE"
   
   echo " Carrier: $CARRIER"

   echo " Goods Code: $GOODSCODE"

   echo " Goods Name: $GOODSNAME"

   echo " Quantity: $GQUANT"

   echo " Measure: $GMEAS"

   echo " Received by: $RECDBY"

   echo ""

   echo " PRESS ENTER to ACCEPT EXISTING ENTRY"

}

#function to post history data

function dohpost()

{

echo "$ORECORD" >> $HOME/GOODS/data/inhgoods.txt

}

#function to post adjusted data

function doapost()

{

   #Find and save records not matching DOCNUM

   grep -v "$DOCNUM" $HOME/GOODS/data/ingoods.txt > $HOME/GOODS/data/tingoods.txt

   mv -f $HOME/GOODS/data/tingoods.txt $HOME/GOODS/data/ingoods.txt

   #Save adjusted record with today's date

   echo "$NDATE#$DOCNUM#$SUPPCODE#$CARRIER#$GOODSCODE#$GOODSNAME#$GQUANT#$GMEAS#$RECDBY" >>
   $HOME/GOODS/data/ingoods.txt

}

#Main program

#colour the screen

tput setb 6

tput clear

#Get the docket number

echo ""

echo ""

echo " INWARDS GOODS ADJUSTMENT"

echo ""

echo ""

echo " Enter Entry Docket Number for Adjustment:"

tput cup 5 44

DOCNUM=""

while [ ${#DOCNUM} -lt 1 ]

do

   tput cup 5 44

   read DOCNUM

done

#Get the record and fill the variables

ORECORD=`grep "$DOCNUM" $HOME/GOODS/data/ingoods.txt`

#Test for valid record

if [ "${#ORECORD}" -lt 1 ]

then

   tput cup 7 10

   echo "Docket Number not in Inwards Goods Record"

   #Give a quit message

   tput cup 8 10

   echo "Press Enter to return to menu"

   read menu

   $HOME/GOODS/bin/inwards.sh

fi

#Set today's date for new record

NDATE=`date +%d/%m/%y`

#Assign variables from ORECORD

EDATE=`echo $ORECORD | cut -d"#" -f1`

SUPPCODE=`echo $ORECORD | cut -d"#" -f3`

CARRIER=`echo $ORECORD | cut -d"#" -f4`

GOODSCODE=`echo $ORECORD | cut -d"#" -f5`

GOODSNAME=`echo $ORECORD | cut -d"#" -f6`

GQUANT=`echo $ORECORD | cut -d"#" -f7`

GMEAS=`echo $ORECORD | cut -d"#" -f8`

RECDBY=`echo $ORECORD | cut -d"#" -f9`

#Loop around each field looking for new data or the enter key

DUNIT="ZERO"

while [ "$DUNIT" = "ZERO" ]

do

   scrnpaint

   tput cup 7 30

   read DUNIT

   if [ "${#DUNIT}" -lt 1 ]

   then

      SUPPCODE="$SUPPCODE"

   else

      if [ "$DUNIT" != "ZERO" ]

      then

         SUPPCODE=$DUNIT

      fi

   fi

done

DUNIT="ZERO"

while [ "$DUNIT" = "ZERO" ]

do

   scrnpaint

   tput cup 8 30

   read DUNIT

   if [ "${#DUNIT}" -lt 1 ]

   then

      CARRIER="$CARRIER"

   else

      if [ "$DUNIT" != "ZERO" ]

      then

         CARRIER=$DUNIT

      fi

   fi

done

DUNIT="ZERO"

while [ "$DUNIT" = "ZERO" ]

do

   scrnpaint

   tput cup 9 30

   read DUNIT

   if [ "${#DUNIT}" -lt 1 ]

   then

      GOODSCODE="$GOODSCODE"

   else

      if [ "$DUNIT" != "ZERO" ]

      then

         GOODSCODE=$DUNIT

      fi

   fi

done

DUNIT="ZERO"

while [ "$DUNIT" = "ZERO" ]

do

   scrnpaint

   tput cup 10 30

   read DUNIT

   if [ "${#DUNIT}" -lt 1 ]

   then

      GOODSNAME="$GOODSNAME"

   else

      if [ "$DUNIT" != "ZERO" ]

      then

         GOODSNAME=$DUNIT

      fi

   fi

done

DUNIT="ZERO"

while [ "$DUNIT" = "ZERO" ]

do

   scrnpaint

   tput cup 11 30

   read DUNIT

   if [ "${#DUNIT}" -lt 1 ]

   then

      GQUANT="$GQUANT"

   else

      if [ "$DUNIT" != "ZERO" ]

      then

         GQUANT=$DUNIT

      fi

   fi

done

DUNIT="ZERO"

while [ "$DUNIT" = "ZERO" ]

do

   scrnpaint

   tput cup 12 30

   read DUNIT

   if [ "${#DUNIT}" -lt 1 ]

   then

      GMEAS="$GMEAS"

   else

      if [ "$DUNIT" != "ZERO" ]

      then

         GMEAS=$DUNIT

      fi

   fi

done

DUNIT="ZERO"

while [ "$DUNIT" = "ZERO" ]

do

   scrnpaint

   tput cup 13 30

   read DUNIT

   if [ "${#DUNIT}" -lt 1 ]

   then

      RECDBY="$RECDBY"

   else

      if [ "$DUNIT" != "ZERO" ]

      then

         RECDBY=$DUNIT

      fi

   fi

done

tput cup 17 10

echo "OK to Post Entry (Y or N):"

tput cup 17 37

read OKPOST

POSTOK=`echo $OKPOST | tr a-z A-Z`

if [ "$POSTOK" = "Y" ]

then

   #Save old history data

   dohpost

   #save new adjusted data

   doapost

fi

#return to calling menu.

$HOME/GOODS/bin/inwards.sh


Now that you've learned how to use "tput", I'm going to show an even better way of doing terminal based screens in the next article.

One of the problems with the "tput" method is we can't go back up the screen to change input mistakes. With this new tool you can do all of that, and some other fancy things like we've been used to using Runtime Revolution in the GUI.

The tool is called "dialog" which processes its commands inside a shell script to give you a really professional looking out put. I sometimes think professional looking equates to boring, but you can change that if you want with this tool.


Novell Cool Solutions (corporate web communities) are produced by WebWise Solutions. www.webwiseone.com

© 2014 Novell