Online Book Reader

Home Category

Classic Shell Scripting - Arnold Robbins [106]

By Root 846 0
envvar pattern(s)

$ echo $?

1

$ pathfind NOSUCHPATH ls

Empty directory search path

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

$ echo $?

1

Then we supply some nonsense filenames:

$ pathfind -a PATH foobar

foobar: not found

$ echo $?

1

$ pathfind -a PATH "name with spaces"

name with spaces: not found

$ echo $?

1

The empty filename list test is next:

$ pathfind PATH

$ echo $?

0

Here's what happens when a quickly typed Ctrl-C interrupts the running program:

$ pathfind PATH foo

^C

$ echo $?

130

The exit code is 128 + 2, indicating that signal number 2 was caught and terminated the program. On this particular system, it is the INT signal, corresponding to interactive input of the keyboard interrupt character.

So far, error reporting is exactly as we intended. Now let's search for files that we know exist, and exercise the -a option:

$ pathfind PATH ls

/usr/local/bin/ls

$ echo $?

0

$ pathfind -a PATH ls

/usr/local/bin/ls

/bin/ls

$ echo $?

Next, we check the handling of a quoted wildcard pattern that must match files that we know exist:

$ pathfind -a PATH '?sh'

/usr/local/bin/ksh

/usr/local/bin/zsh

/bin/csh

/usr/bin/rsh

/usr/bin/ssh

Then we do the same for a pattern that should not match anything:

$ pathfind -a PATH '*junk*'

*junk*: not found

Now for a big test: find some C and C++ compilers on this system:

$ pathfind -a PATH c89 c99 cc c++ CC gcc g++ icc lcc pgcc pgCC

c89: not found

c99: not found

/usr/bin/cc

/usr/local/bin/c++

/usr/bin/c++

CC: not found

/usr/local/bin/gcc

/usr/bin/gcc

/usr/local/gnat/bin/gcc

/usr/local/bin/g++

/usr/bin/g++

/opt/intel_cc_80/bin/icc

/usr/local/sys/intel/compiler70/ia32/bin/icc

/usr/local/bin/lcc

/usr/local/sys/pgi/pgi/linux86/bin/pgcc

/usr/local/sys/pgi/pgi/linux86/bin/pgCC

$ echo $?

3

An awk one-liner lets us verify that the exit-code counter logic works as intended. We try 150 nonexistent files, but the exit code correctly caps at 125:

$ pathfind PATH $(awk 'BEGIN { while (n < 150) printf("x.%d ", ++n) }' )

x.1: not found

...

x.150: not found

$ echo $?

125

Our final test verifies that standard error and standard output are handled as promised, by capturing the two streams in separate files, and then showing their contents:

$ pathfind -a PATH c89 gcc g++ >foo.out 2>foo.err

$ echo $?

1

$ cat foo.out

/usr/local/bin/gcc

/usr/bin/gcc

/usr/local/gnat/bin/gcc

/usr/local/bin/g++

/usr/bin/g++

$ cat foo.err

c89: not found

At this point, we can probably declare our pathfind command a success, although some shell wizard might still be able to spot a hole[1] in it, and there is no substitute for extensive testing, particularly with unexpected input, such as from the fuzz tests cited in a footnote in Section B.3 in Appendix B. Ideally, testing should exercise every combination of legal, and at least one illegal, argument. Since we have three main option choices, each with several abbreviations, there are (6 + 1) (10 + 1) × (14 + 1) = 1155 option combinations, and each of these needs to be tested with zero, one, two, and at least three remaining arguments. We know from our implementation that the option abbreviations are handled the same way so that many fewer tests are necessary. However, when we put on our testing hat, we must first view the program as a black box whose contents are unknown, but which is documented to behave a certain way. Later, we should put on a different testing hat, sneak inside the program, and then knowing how it works, try hard to figure out how to break it. Also, test data needs to be devised that can be shown to exercise every single line of the program. Exhaustive testing is tedious!

Because undocumented software is likely to be unusable software, and because few books describe how to write manual pages, we develop a manual page for pathfind in Appendix A.

pathfind has proved a valuable exercise. Besides being a handy new tool that isn't available in the standard GNU, POSIX, and Unix toolboxes, it has all the major elements of most Unix

Return Main Page Previous Page Next Page

®Online Book Reader