next up previous contents
Next: Bibliography Up: Solutions to Exercises Previous: Solutions to Exercises

Programming the Shells

The scripts shown below are all Bourne shell based. C shell scripts could also be written to solve these problems.

Most of the scripts lack error-checking mechanisms such as verifying the number of arguments, checking if a file exists before creating it, etc. The addition of such tests is good programming practice; their inclusion is left to the reader as further exercises.

  1. Once the REXX script is written, the execution mode should be set (chmod +x script.rexx). NOTE, the first line of the script must look like
    #!/usr/local/bin/rexx
    so that the rexx shell is invoked to run the commands.
  2. This exercise makes use of the grave accents (also called back quotes) to get the output from the date command.
        #!/bin/sh
        echo "The current date is `date`."
        exit 0
  3. The output from the date command is stored in a variable and redisplayed 5 seconds later.

        #!/bin/sh
        DATE=`date`
        echo "Current: $DATE."
        sleep 5
        echo "5 seconds late: $DATE."
        exit 0
  4. The argument on the program line is referred to as $1.
    	#!/bin/sh
    
    	if test $# -eq 0
    	then
    	    echo "No name on command line."
    	    exit 1
    	fi
    
    	echo "Good Day $1, How are you today?"
    	exit 0
  5. The only difference with the previous exercise is the way the name is read by the script:
    	#!/bin/sh
    
    	echo "Enter you name here: "; read NAME
    
    	echo "Good Day $NAME, How are you today?"
    	exit 0
  6. This script is really a ``one-liner":
    	#!/bin/sh
    
    	echo "There were $# arguments on the command line."
    	exit 0
  7. This solution is:
    	#!/bin/sh
    
    	NUM=0
    	for i in $* 
    	do           
    	    NUM=`expr $NUM + 1`
    	done
    	echo "There were $NUM arguments."
    	exit 0

    	#!/bin/sh
    
    	NUM=0
    	while test $# -gt 0
    	do
    	    NUM=`expr $NUM + 1`
     	   shift               
    	done
    	echo "There were $NUM arguments."
    	exit 0

    	#!/bin/sh
    
    	NUM=0
    	until test $# -eq 0
    	do                  
    	    NUM=`expr $NUM + 1`
     	   shift
    	done
    	echo "There were $NUM arguments."
    	exit 0
  8. First, one should verify that the third parameter actually exists:
    	#!/bin/sh
    
    	if test $# -ge 3
    	then             
     	   echo "The third argument is $3."
    	else
     	   echo "There were only $# parameters."
     	   echo "Program stopped."
    	fi                          
    	exit 0
  9. One such script could be
    	#!/bin/sh
    	# script to print lowest and highest number from a file.
    	#
    	if test $# -eq 0
    	then
     	   echo usage: minmax filename
     	   exit 1
    	fi
    
    	sort -n numbers > sorted.numbers
    
    	read SMALLEST < sorted.numbers
    	LARGEST=`tail -1 sorted.numbers`
    
    	rm sorted.numbers
    
    	echo " "
    	echo "The smallest number is $SMALLEST."
    	echo "The largest number is $LARGEST."
    	echo " "
     	exit 0

    This script should contain code to check that sorted.numbers does not already exist. It is left to the reader to add that code.

  10. This makes use of pattern matching within the case statement.

        #!/bin/sh
        echo "Enter a word or number: \c"; read ANS
        case $ANS in
          [a-z]*) echo "lower case"
                ;;
          [A-Z]*) echo "upper case"
                ;;
          [0-9]*) echo "number."
                ;;
          *) echo "not upper, lower, or number."
        esac
        exit 0
  11. This uses an infinite while loop and the break command.

        #!/bin/sh
        FILE="myfile"
        if test -f $FILE
        then
           echo "File already exist."
        else
           echo "creating myfile."
           touch myfile
           while :
           do
               echo "would you like to erase it? \c"
               read ANS
               case $ANS in
                  [yY] | [yY][eE][sS])  echo "Fine, then we'll erase it."
                           rm myfile
                           break
                           ;;
                  [nN] | [nN][oO]) echo "OK we will keep it, then."
                           break
                           ;;
                  *) echo "You must enter a yes or no!"
               esac
           done
       
        fi
        exit 0
  12. This is a toughy, especially if you have no idea what awk is. The following script will take either a FORTRAN or a C program, and compile it using the default flags:
    	#!/bin/sh
    	
    	if test $# -eq 0
    	then
    	    echo " "
    	    echo "Enter program to be compiled."
     	   read PROGRAM
    	else
    	    PROGRAM=$1
    	fi
    
    	NAME=`echo $PROGRAM | awk -F. '{print $1}'`
    	make $NAME
  13. This script uses du and awk to find the solution:
    	#!/bin/sh
    
    	CURRENT_DIR=`echo $cwd`
    	cd
    	cd ..
    	LAST_LINE=`du $user | tail -1`
    	SPACE=`echo $LAST_LINE | awk '{print $1}'`
    
    	echo "My home directory is using $SPACE kilobytes."
    
    	cd $CURRENT_DIR
  14. This script makes use of the creation of a few temporary files, and of the read statement on one of those files. Note where the input redirection sign is placed: this ensures that the file is kept open during the read process.
    	#!/bin/sh
    
    	ls > /tmp/listing
    	SIZE=`cat /tmp/listing | wc -l`
    	NUM=0
    	while [ $NUM -lt $SIZE ]
    	do
     	   read FILE
     	   if [ -f $FILE ]
     	   then
     	       echo $FILE >> files
    	    elif [ -d $FILE ]
    	    then
    	        echo $FILE >> dirs
    	    fi
    	    NUM=`expr $NUM + 1`
    	done < /tmp/listing
    
    	echo "Files:"
    	echo "-----"
    	cat files
    	echo " "
    	echo "Directories:"
    	echo "-----------"
    	cat dirs
    
    	rm files dirs /tmp/listing

    Note that no test strings appear in this program. Instead, open and closed square brackets were used ([ ]). These can be used interchangeably instead of the test command.

  15. This is simple:
    	#!/bin/sh
    
    	echo "There are `who | wc -l` users in the system."
  16. Again, this is fairly straightforward:
    	#!/bin/sh
    
    	if [ $# -eq 0 ]
    	then
     	   echo There were no arguments on the command line.
     	   exit
    	fi
    
    	ARGS=""
    	while [ !  $# -eq 0 ]
    	do
    	    ARGS="$1 $ARGS"
     	   shift
    	done
    
    	echo "The reversed arguments are $ARGS"
  17. This script makes use of the % operation:
    	#!/bin/sh
    
    	REM=`expr $# % 2`
    	if [ $REM -eq 0 ]
    	then
    	    echo "There were an even number of arguments."
    	else
    	    echo "There were an odd number of arguments."
    	fi
    	exit 0
  18. Again, this script makes use of the expr command.
    	#!/bin/sh
    
    	HIGHEST=0
    	LOWEST=99999999
    	echo "Please input numbers: "
    	read NUMBER
    	while [ $NUMBER -ne 0 ]
    	do
    	    if test $NUMBER -gt $HIGHEST
     	   then
     	       HIGHEST=$NUMBER
     	   fi
     	   if test $NUMBER -lt $LOWEST
     	   then
     	       LOWEST=$NUMBER
     	   fi
    	    read NUMBER
    	done
    	echo " "
     	echo "user: $USER"
    	echo " "
    	if [ $HIGHEST -eq 0 -a  $LOWEST -eq 99999999 ]
    	then
     	   echo "No numbers were entered."
    	else
     	   echo "Lowest number entered: $LOWEST"
     	   echo "Highest number entered: $HIGHEST"
     	   DIFF=`expr $HIGHEST - $LOWEST`
     	   echo "Difference between the two: $DIFF"
     	   PROD=`expr $LOWEST "*" $HIGHEST`
     	   echo "Product of the two: $PROD"
    	    echo " "
    	fi
  19. This could be useful for unique temporary file names.

        #!/bin/sh
        TMPFILE="/tmp/an16.$$"
        if test -f $TMPFILE
        then
          echo "Temporary file exists!!!"
          exit
        fi
    
        date > $TMPFILE
        echo $USER >> $TMPFILE
    
        echo "\ncontent of $TMPFILE is:"
        echo "------"
        cat $TMPFILE
    
        sleep 30
        rm $TMPFILE
        exit 0

    Run the script in the background, then start another. Their temporary file names will not conflict.

  20. To change command line parameters:
        #!/bin/sh
        echo "Current parameters are: $*"
        set $USER
        echo "New Current parameters are: $*"
        exit 0
  21. This uses the trap command.

        #!/bin/sh
        trap 'echo "Ignoring Control-C..."' 2
        for i in 1 2 3 4 5 6 7 8
        do
          sleep 2
        done
        echo "program now terminated normally..."
        exit 0
  22. Useful to hide passwords.

        #!/bin/sh
    
        echo "\nEnter a secret word: \c"
        stty -echo
        read SECRET
        stty echo
    
        echo "\nYour secret word is $SECRET."
        exit 0


next up previous contents
Next: Bibliography Up: Solutions to Exercises Previous: Solutions to Exercises

Claude Cantin
Sun Sep 1 02:02:26 EDT 2002