Online Book Reader

Home Category

Classic Shell Scripting - Arnold Robbins [156]

By Root 1002 0
single argument, and otherwise, prints a brief error message on standard error and exits with a nonzero status value:

if [ $# -ne 1 ]

then

echo "Usage: $0 directory" >&2

exit 1

fi

As a final security feature, the script invokes umask to limit access to the owner of the output files:

umask 077 # ensure file privacy

filesdirectories allows the default temporary file directory to be overridden by the TMPDIR environment variable:

TMP=${TMPDIR:-/tmp} # allow alternate temporary directory

It then initializes TMPFILES to a long list of temporary files that collect the output:

TMPFILES="

$TMP/DIRECTORIES.all.$$ $TMP/DIRECTORIES.all.$$.tmp

$TMP/DIRECTORIES.last01.$$ $TMP/DIRECTORIES.last01.$$.tmp

$TMP/DIRECTORIES.last02.$$ $TMP/DIRECTORIES.last02.$$.tmp

$TMP/DIRECTORIES.last07.$$ $TMP/DIRECTORIES.last07.$$.tmp

$TMP/DIRECTORIES.last14.$$ $TMP/DIRECTORIES.last14.$$.tmp

$TMP/DIRECTORIES.last31.$$ $TMP/DIRECTORIES.last31.$$.tmp

$TMP/FILES.all.$$ $TMP/FILES.all.$$.tmp

$TMP/FILES.last01.$$ $TMP/FILES.last01.$$.tmp

$TMP/FILES.last02.$$ $TMP/FILES.last02.$$.tmp

$TMP/FILES.last07.$$ $TMP/FILES.last07.$$.tmp

$TMP/FILES.last14.$$ $TMP/FILES.last14.$$.tmp

$TMP/FILES.last31.$$ $TMP/FILES.last31.$$.tmp

"

These output files contain the names of directories and files in the entire tree (*.all.*), as well as the names of those modified in the last day (*.last01.*), last two days (*.last02.*), and so on.

The WD variable saves the argument directory name for later use, and then the script changes to that directory:

WD=$1

cd $WD || exit 1

Changing the working directory before running find solves two problems:

If the argument is not a directory, or is but lacks the needed permissions, then the cd command fails, and the script terminates immediately with a nonzero exit value.

If the argument is a symbolic link, cd follows the link to the real location. find does not follow symbolic links unless given extra options, but there is no way to tell it to do so only for the top-level directory. In practice, we do not want filesdirectories to follow links in the directory tree, although it is straightforward to add an option to do so.

The trap commands ensure that the temporary files are removed when the script terminates:

trap 'exit 1' HUP INT PIPE QUIT TERM

trap 'rm -f $TMPFILES' EXIT

The exit status value is preserved across the EXIT trap (see Section 13.3.2).

The wizardry, and all of the hard work, come next in the multiline find command. The lines with the -name option match the names of the output files from a previous run, and the -true option causes them to be ignored so that they do not clutter the output reports:

find . \

-name DIRECTORIES.all -true \

-o -name 'DIRECTORIES.last[0-9][0-9]' -true \

-o -name FILES.all -true \

-o -name 'FILES.last[0-9][0-9]' -true \

The next line matches all ordinary files, and the -fprint option writes their names to $TMP/FILES.all.$$:

-o -type f -fprint $TMP/FILES.all.$$ \

The next five lines select files modified in the last 31, 14, 7, 2, and 1 days (the -type f selector is still in effect), and the -fprint option writes their names to the indicated temporary files:

-a -mtime -31 -fprint $TMP/FILES.last31.$$ \

-a -mtime -14 -fprint $TMP/FILES.last14.$$ \

-a -mtime -7 -fprint $TMP/FILES.last07.$$ \

-a -mtime -2 -fprint $TMP/FILES.last02.$$ \

-a -mtime -1 -fprint $TMP/FILES.last01.$$ \

The tests are made in order from oldest to newest because each set of files is a subset of the previous ones, reducing the work at each step. Thus, a ten-day-old file will pass the first two -mtime tests, but will fail the next three, so it will be included only in the FILES.last31.$$ and FILES.last14.$$ files.

The next line matches directories, and the -fprint option writes their names to $TMP/DIRECTORIES.all.$$:

-o -type d -fprint $TMP/DIRECTORIES.all.$$ \

The final five lines of the find command match subsets of directories (the -type d selector still applies) and write their names, just as for files earlier in the command:

-a -mtime -31 -fprint $TMP/DIRECTORIES.last31.$$

Return Main Page Previous Page Next Page

®Online Book Reader