Sams Teach Yourself Shell Programming in 24 Hours
(Publisher: Macmillan Computer Publishing)
Author(s): Sriranga Veeraraghavan
ISBN: 0672314819
Publication Date: 01/01/99

Previous Table of Contents Next


Conditional Execution

A script that uses conditional execution for portability contains an if statement at the beginning. The if statement sets several variables indicating the set of commands to use on a particular platform.

In this section, you look at two common cases of conditional execution:

  Determining the remote shell command
  Determining the proper method of using the echo command in prompts

The first case illustrates setting a variable based on the operating system type. The second case illustrates setting variables based on the behavior of a command (echo) on a particular system.

Executing Remote Commands

A common use of conditional execution is in scripts that need to execute commands on remote systems. On most versions of UNIX, you can use the rsh (remote shell) command to execute commands on a remote system. Unfortunately, you cannot use this command on all versions of UNIX.

On HP-UX, rsh is available, but it is not the remote shell program—it is the restricted shell program. On HP-UX, you need to use the command remsh to execute commands on a remote system.

A script that needs to execute commands on a remote system might have an if statement of the following form at its beginning:

if SystemIS HPUX ; then
    RCMD=remsh
else
    RCMD=rsh
fi

After the variable $RCMD is set, remote commands can execute as follows:

"$RCMD" host command

Here, host is the hostname of the remote system, and command is the command to execute.

Problems with the echo Command in Prompts

Most programs that need to prompt the user need to be able to print a prompt that is not terminated by a newline. In Chapter 13, “Input/Output,” there were several problems with using the \c escape sequence of the echo command to do this. The workaround was to use the /bin/echo command.

Although this works for UNIX versions based on System V, on some BSD-based systems this does not work. You need to specify the -n option to echo instead. By using the following shell script, you can create a shell function, echo_prompt, to display a prompt reliably across all versions of echo:

_ECHO=/bin/echo
_N=
_C="\c"
ECHOOUT=`$_ECHO "hello $_C"`
if [ "$ECHOOUT" = "hello \c" ] ; then
    _N="-n"
    _C=
fi
export _ECHO _N _C

echo_prompt() {  $_ECHO $_N $@ $_C ; }

This script fragment implements the /bin/echo workaround by using it as the base from which to construct the correct echo command. It then checks the output of an echo command to see whether the \c sequence is treated correctly. If it is not, you need to use the -n option.

After this has been determined, the function echo_prompt is created using the correct variables. This function enables us to reliably output prompts, as in the following example:

$ echo_prompt "Do you want to play a game?" ; read response
Do you want to play a game?

Abstraction


Abstraction is a technique used to hide the differences between the versions of UNIX inside shell functions. By doing this, the overall flow of a shell script is not affected. When a function is called, it makes a decision as to what commands to execute.

In this section you look at two different examples of abstraction:

  Adapting the getFreeSpace function to run on HP-UX
  Adapting the getPID function to run on BSD and System V

You make use of the functions getOSName and isOS given earlier in this chapter in order to adapt these functions.

Adapting getFreeSpace for HP-UX

Recall the getFreeSpace function introduced in Chapter 21:

getFreeSpace() {
    if [ $# -lt 1 ] ; then
        echo "ERROR: Insufficient Arguments." >&2
        return 1
    fi

    DIR="$1"
    if [ ! -d "$DIR" ] ; then
        DIR=`/usr/bin/dirname $DIR`
    fi

    df -k "$DIR" | awk 'NR != 1 { print $4 ; }'
}

This function prints the amount of free space in a directory in kilobytes. You use this function’s output in the isSpaceAvailable function to determine whether there is enough space in a particular directory.

Although this works for most systems (Solaris, Linux, BSD), the output of df -k on HP-UX is much different. For example,

$ df -k /usr/sbin
/usr           (/dev/vg00/lvol8       ) :   737344 total allocated Kb
                                            368296 free allocated Kb
                                            369048 used allocated Kb
                                                50 % allocation used

To get a single output line, you need to use the command df -b instead:

$ df –b /usr/sbin
/usr                  (/dev/vg00/lvol8       ) :   392808 Kbytes free

In order to use isSpaceAvailable on all systems, including HP-UX, you need to change the function getFreeSpace to take these factors into account. The modified version looks like the following:

getFreeSpace() {
    if [ $# -lt 1 ] ; then
        echo "ERROR: Insufficient Arguments." >&2
        return 1
    fi

    DIR="$1"
    if [ ! -d "$DIR" ] ; then
        DIR=`/usr/bin/dirname $DIR`
    fi

    if isOS HPUX ; then
        df -b "$DIR" | awk '{ print $5 ; }'
    else
        df -k "$DIR" | awk 'NR != 1 { print $4 ; }'
    fi
}

Here, you are calling the isOS function given earlier in this chapter to determine which commands to execute.


Previous Table of Contents Next