Classic Shell Scripting - Arnold Robbins [107]
As an exercise, you might consider what needs to be changed for these extensions to pathfind:
To save redirections of standard output and standard error to /dev/null, add a —quiet option to suppress all output so that the only indication of whether a match was found is the exit code. There is precedence for this programming convenience in cmp's -s option and grep's -q option.
Add a —trace option to echo on standard error the full path for every file tested.
Add a —test x option to allow the test option -f to be replaced by some other one, such as -h (file is a symbolic link), -r (file is readable), -x (file is executable), and so on.
Make pathfind act like a filter: when no files are named on the command line, it should read a list of files from standard input. How does this affect the program's structure and organization?
Patch any security holes that you can find, such as those listed in the most recent footnote.
* * *
[1] Notable security holes include altering the input field separator (IFS); substituting rogue commands for trusted ones by altering the search path; sneaking backquoted commands, shell metacharacters, and control characters (including NUL and newline) into arguments; causing unexpected runtime interrupts; and passing arguments that are too long for various internal shell resource limits.
Automating Software Builds
Because Unix runs on so many different platforms, it is common practice to build software packages from source code, rather than installing binary distributions. Large Unix sites often have multiple platforms, so their managers have the tedious job of installing packages on several systems. This is clearly a case for automation.
Many software developers now adopt software-packaging conventions developed within the GNU Project. Among them are:
Packages that are distributed in compressed archive files named package-x.y.z.tar.gz (or package-x.y.z.tar.bz2) that unbundle into a directory named package-x.y.z.
A top-level configure script, usually generated automatically by the GNU autoconf command from a list of rules in the configure.in or configure.ac file. Executing that script, sometimes with command-line options, produces a customized C/C++ header file, usually called config.h, a customized Makefile, derived from the template file Makefile.in, and sometimes, a few other files.
A standard set of Makefile targets that is documented in The GNU Coding Standards, among them all (build everything), check (run validation tests), clean (remove unneeded intermediate files), distclean (restore the directory to its original distribution), and install (install all needed files on the local system).
Installed files that reside in directories under a default tree defined by the variable prefix in the Makefile and is settable at configure time with the —prefix=dir command-line option, or supplied via a local system-wide customization file. The default prefix is /usr/local, but an unprivileged user could use something like $HOME/local, or better, $HOME/`arch`/local, where arch is a command that prints a short phrase that defines the platform uniquely. GNU/Linux and Sun Solaris provide /bin/arch. On other platforms, we install our own implementations, usually just a simple shell-script wrapper around a suitable echo command.
The task is then to make a script that, given a list of packages, finds their source distributions in one of several standard places in the current