Previous | Table of Contents | Next |
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:
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 programit 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 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:
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 functions 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 |