Previous Table of Contents Next


EXAMPLE BOURNE SHELL SCRIPTS

The bnl script is the Bourne shell version of the UNIX nl command. It displays line-numbered output.

#!/bin/sh
#
#    bnl - Bourne shell line-numbering filter
#    A Olczak - ASP, Inc
#

# Initialize line number counter
LNUM=1

# Check usage
if [ "$#" -eq 0 ]
then
     echo "Usage: $0 file"
     exit 1
fi

# Process each file
for FILE
do
     # Make sure file exists
     if [ ! -f "$FILE" ]
     then
          echo "$FILE: non-existent or not accessible"
          exit 1
     fi

     # Read each line, display with line number
     cat $FILE | while read LINE
     do
          echo "$LNUM: $LINE"
          LNUM=`expr $LNUM + 1`
     done

     # Reset line number counter
     LNUM=1
done

The kcal script implements a menu-driven calendar program. It supports addition, deletion, modification, and listing of calendar entries. It also provides the ability to find the calendar entry for the current day and list all calendar entries.

#!/bin/sh
#
#   bcal - Bourne shell calendar program
#
#   Anatole Olczak - ASP, Inc
#

# Check arguments
if [ "$#" -gt 0 ]
then
     echo "Usage: $0"
     exit 1
fi

# Use variable setting or default
: ${CALFILE:=$HOME/.calfile}

# Create calendar file if non-existent; flag
# creation error
if [ ! -f "$CALFILE" ]
then
     echo "Creating default $HOME/.calfile"
     > $HOME/.calfile || { echo "$HOME/.calfile: \
     cannot create" ; exit 1 ; }
fi
# Variable declaration/assignment
DATE= LINE= ENTRY= REPLY="yes"
PAGER=/bin/more CLEAR=/bin/clear

# Set trap to not allow interrupts
trap '$CLEAR; echo "\007Interrupt ignored - use \
menu to quit.  Press <Return> to continue."; \
read TMP; $CLEAR' 2 3

# Check the date
checkdate() {
    while true
    do
            # Prompt for date
       echo "Enter date in mmdd[yy] format (default today):\c"

       read DATE

       case $DATE in

           # Default - use todays date
           "" )  DATE=`date +%m%d%y` break ;;

          # Integer argument
               [0-9]* )
               LENGTH=`echo $DATE | wc -c | sed -e 's/^
          //p'`
    
               # Verify date length
               case "$LENGTH" in

                  5 )       MO=`echo $DATE | cut -c1,2`
                            DA=`echo $DATE | cut -c3,4`
                            YR=`date +%y`

DATE=$MO$DA$YR
                                              ;;
                  7 )       MO=`echo $DATE | cut -c1,2`
                            DA=`echo $DATE | cut -c3,4`
                            YR=`echo $DATE | cut -c5,6`
                                              ;;
                  * )       echo "Invalid date format - try again"
                            continue
                                              ;;
                  esac

               # Validate date/month
                    if [ "$DA" -gt 00 -a "$DA" -lt 32 ]
                    then
                       if [ "$MO" -gt 00 -a "$MO" -lt 13 ]
                       then
                          break
                       else
                          echo "$MO: invalid month format - try again"
                       fi
                    else
                       echo "$DA: invalid day format - try again"

                    fi

                       ;;

               # Invalid date given
               * )      echo "$DATE: invalid format - try again" ;;
      esac
     done
}

# Change an entry
changeentry() {

     # Find entry - put it in temp found file
     grep $DATE $CALFILE | tr ',' '\012'>/tmp/.FOUND$$

     # Return if no entry was found
     if [ ! -s /tmp/.FOUND$$ ]
     then
          $CLEAR
          echo "Entry for $DATE not found - press
          <Return> to continue\c"
          read TMP
          return
     fi
     # Prompt again for change
     while [ "$REPLY" != "" ]
     do
          echo "Change/Add to entry for <$DATE>?\c"
          read REPLY

          case $REPLY in

            [yY]* | "" )
               break ;;

            [nN]* )  echo "Ok, aborting entry change"
               return ;;

            * ) echo "Invalid reply - try again." ;;

          esac
     done

     # Edit the temporary found file
     ${EDITOR:-vi} /tmp/.FOUND$$

     # Remove the specified original entry
     grep -v $DATE $CALFILE > /tmp/.CHANGE$$

     # Put back new change in record format.
     # Add trailing \n
     (cat /tmp/.FOUND$$ | tr '\012' ',' ; echo ) \
     >>/tmp/.CHANGE$$

     # Put back new file
     cat /tmp/.CHANGE$$ > $CALFILE

     # Clean up tmp files
     rm -rf /tmp/.CHANGE$$ /tmp/.FOUND$$
}
# Add new calendar entry
addentry() {

     $CLEAR
     ENTRY="$DATE"

     # For existent entry, just add more data
     COUNT=`grep -c "^$DATE" $CALFILE`
     if [ "$COUNT" -gt 0 ]
     then
          changeentry
          return
     fi

     # Prompt for input
     echo "Enter info for $DATE: (enter <Return> by
          itself when finished)"
     while true
     do
          echo "=>\c"
          read LINE
          if [ -n "$LINE" ]
          then
               ENTRY="$ENTRY,$LINE"
          else
               break
          fi
     done

     # Append to calendar file
     echo $ENTRY>>$CALFILE

     # Sort the calendar file
     sort -o $CALFILE $CALFILE
}

formatentry() {

     $CLEAR
     X=$IFS
     IFS=","
     BORDER="**********************************"
     BORDER1="*                 *"
     REPLY=yes
     TFILE=$1

     if [ -s "$TFILE" ]
     then

          # Open calendar file for reading, and
          # format output
          (cat $TFILE | while read ENTRY
          do
               echo "$BORDER\n$BORDER1"
               set $ENTRY
               echo "                *\r*  DATE: $1"
               echo "$BORDER1"
               shift
               for i
               do
                    echo "               *\r*     $i"
               done
               echo "$BORDER1"
          done
          echo "$BORDER"
          ) | $PAGER
     else
          echo "No entries found."
     fi
     IFS=$X

     # Prompt to continue
     until [ "$REPLY" = "" ]
     do
          echo "Enter <Return> to continue...\c"
          read REPLY
     done
}

# Find specific entry
findentry() {

     $CLEAR
     # Check for entry - put it in temp found file
     grep "$DATE" $CALFILE >/tmp/.FOUND$$

     # Format found entries
     #TFILE=/tmp/.FOUND$$
     formatentry /tmp/.FOUND$$

     # Clean up temp files
     rm -rf /tmp/.FOUND$$
}

# Remove specific entry
delentry() {

     # Look for entry
     grep "$DATE" $CALFILE >/tmp/.FOUND$$

     # Return if not found
     if [ ! -s /tmp/.FOUND$$ ]
     then
          $CLEAR
          echo "Entry for $DATE not found - press
          <Return> to continue\c"
          read TMP
          return
     fi

     # Prompt to delete
     while [ "$REPLY" != "" ]
     do
          echo "Delete entry for <$DATE>?\c"
          read REPLY

          case $REPLY in
             [yY]* | "" )
                break ;;

             [nN]* )     echo "ok, aborting delete"
                return ;;

             * )      echo "Invalid reply - try again." ;;

          esac
     done

     # Merge changes - put them in temporary file
     grep -v "$DATE" $CALFILE > /tmp/.DEL$$

     # Put back new file
     cat /tmp/.DEL$$ > $CALFILE

     # Clean up tmp files
     rm -rf /tmp/.DEL$$ /tmp/.FOUND$$
}

# Set menu selection prompt
PS3="Enter selection or <Return> for default menu:"

# Display menu
while true
do
     $CLEAR

     echo "        *** CALENDAR PROGRAM *** \n\n"
     echo "     1) Add calendar entry\n"
     echo "     2) Delete calendar entry\n"
     echo "     3) Change calendar entry\n"
     echo "     4) Find calendar entry\n"
     echo "     5) List all calendar entries\n"
     echo "     6) List todays calendar entry\n"
     echo "     7) Exit\n\n"
     echo "$PS3\c"
     read i

     case $i in
          "1")    checkdate
                  addentry
                  $CLEAR ;;
          "2")    checkdate
                  delentry
                  $CLEAR ;;
          "3")    checkdate
                  changeentry
                  $CLEAR ;;
          "4")    checkdate
                  findentry
                  $CLEAR ;;
          "5")    formatentry $CALFILE
                  $CLEAR ;;
          "6")    DATE=`date +%m%d%y`
                  findentry
                  $CLEAR ;;
          "7")    # Clean up files
                  rm -rf /tmp/.FOUND$$ /tmp/.CHANGE$$
          /tmp/.DEL$$
                  exit ;;
          * )     echo "\n\nInvalid selection - press
          <Return> to continue\c"
                  read TMP
                  $CLEAR
                  continue ;;
     esac
done


Previous Table of Contents Next
1