Online Book Reader

Home Category

Classic Shell Scripting - Arnold Robbins [105]

By Root 926 0

test -z "$result" && warning "$pattern: not found"

done

At the completion of the outer loop, we have looked for every requested match in every directory in the search path, and we are ready to return to the invoking program. There is only one small problem left to deal with: user exit-code values are limited to the range 0 through 125, as shown in Table 6-5 in Chapter 6, so we cap the EXITCODE value at 125:

test $EXITCODE -gt 125 && EXITCODE=125

Our program is almost complete: its last statement returns to the parent process with an explicit exit status, as all well-behaved Unix programs should. That way, the parent can test the exit status to determine whether the child process succeeded or failed:

exit $EXITCODE

In Example 8-1, we present the complete text of pathfind, without our commentary, so that you can see it as the shell sees it. The total length is about 90 lines, ignoring comments and empty lines.

Example 8-1. Searching a path for input files

#! /bin/sh -

#

# Search for one or more ordinary files or file patterns on a search

# path defined by a specified environment variable.

#

# The output on standard output is normally either the full path

# to the first instance of each file found on the search path,

# or "filename: not found" on standard error.

#

# The exit code is 0 if all files are found, and otherwise a

# nonzero value equal to the number of files not found (subject

# to the shell exit code limit of 125).

#

# Usage:

# pathfind [--all] [--?] [--help] [--version] envvar pattern(s)

#

# With the --all option, every directory in the path is

# searched, instead of stopping with the first one found.

IFS='

'

OLDPATH="$PATH"

PATH=/bin:/usr/bin

export PATH

error( )

{

echo "$@" 1>&2

usage_and_exit 1

}

usage( )

{

echo "Usage: $PROGRAM [--all] [--?] [--help] [--version] envvar pattern(s)"

}

usage_and_exit( )

{

usage

exit $1

}

version( )

{

echo "$PROGRAM version $VERSION"

}

warning( )

{

echo "$@" 1>&2

EXITCODE=`expr $EXITCODE + 1`

}

all=no

envvar=

EXITCODE=0

PROGRAM=`basename $0`

VERSION=1.0

while test $# -gt 0

do

case $1 in

--all | --al | --a | -all | -al | -a )

all=yes

;;

--help | --hel | --he | --h | '--?' | -help | -hel | -he | -h | '-?' )

usage_and_exit 0

;;

--version | --versio | --versi | --vers | --ver | --ve | --v | \

-version | -versio | -versi | -vers | -ver | -ve | -v )

version

exit 0

;;

-*)

error "Unrecognized option: $1"

;;

*)

break

;;

esac

shift

done

envvar="$1"

test $# -gt 0 && shift

test "x$envvar" = "xPATH" && envvar=OLDPATH

dirpath=`eval echo '${'"$envvar"'}' 2>/dev/null | tr : ' ' `

# sanity checks for error conditions

if test -z "$envvar"

then

error Environment variable missing or empty

elif test "x$dirpath" = "x$envvar"

then

error "Broken sh on this platform: cannot expand $envvar"

elif test -z "$dirpath"

then

error Empty directory search path

elif test $# -eq 0

then

exit 0

fi

for pattern in "$@"

do

result=

for dir in $dirpath

do

for file in $dir/$pattern

do

if test -f "$file"

then

result="$file"

echo $result

test "$all" = "no" && break 2

fi

done

done

test -z "$result" && warning "$pattern: not found"

done

# Limit exit status to common Unix practice

test $EXITCODE -gt 125 && EXITCODE=125

exit $EXITCODE

Let's wrap up this section with some simple tests of our program, using a search path, PATH, that Unix systems always have. Each test includes a display of the exit code, $?, so that we can verify the error handling. First, we check the help and version options:

$ pathfind -h

Usage: pathfind [--all] [--?] [--help] [--version] envvar pattern(s)

$ echo $?

0

$ pathfind --version

pathfind version 1.0

$ echo $?

Next, we provoke some error reports with bad options, and missing arguments:

$ pathfind --help-me-out

Unrecognized option: --help-me-out

Usage: pathfind [--all] [--?] [--help] [--version] envvar pattern(s)

$ echo $?

1

$ pathfind

Environment variable missing or empty

Usage: pathfind [--all] [--?] [--help] [--version]

Return Main Page Previous Page Next Page

®Online Book Reader