Classic Shell Scripting - Arnold Robbins [121]
usage_and_exit 0
;;
--logdirectory | --logdirector | --logdirecto | --logdirect | \
--logdirec | --logdire | --logdir | --logdi | --logd | --log | \
--lo | --l | \
-logdirectory | -logdirector | -logdirecto | -logdirect | \
-logdirec | -logdire | -logdir | -logdi | -logd | -log | -lo | -l )
shift
altlogdir="$1"
;;
--on | --o | -on | -o )
shift
userhosts="$userhosts $1"
;;
--source | --sourc | --sour | --sou | --so | --s | \
-source | -sourc | -sour | -sou | -so | -s )
shift
altsrcdirs="$altsrcdirs $1"
;;
--userhosts | --userhost | --userhos | --userho | --userh | \
--user | --use | --us | --u | \
-userhosts | -userhost | -userhos | -userho | -userh | \
-user | -use | -us | -u )
shift
set_userhosts $1
;;
--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
# Find a suitable mail client
for MAIL in /bin/mailx /usr/bin/mailx /usr/sbin/mailx /usr/ucb/mailx \
/bin/mail /usr/bin/mail
do
test -x $MAIL && break
done
test -x $MAIL || error "Cannot find mail client"
# Command-line source directories precede defaults
SRCDIRS="$altsrcdirs $SRCDIRS"
if test -n "$userhosts"
then
test -n "$ALTUSERHOSTS" &&
userhosts="$userhosts `$STRIPCOMMENTS $ALTUSERHOSTS 2> /dev/null`"
else
test -z "$ALTUSERHOSTS" && ALTUSERHOSTS="$defaultuserhosts"
userhosts="`$STRIPCOMMENTS $ALTUSERHOSTS 2> /dev/null`"
fi
# Check for something to do
test -z "$userhosts" && usage_and_exit 1
for p in "$@"
do
find_package "$p"
if test -z "$PARFILE"
then
warning "Cannot find package file $p"
continue
fi
LOGDIR="$altlogdir"
if test -z "$LOGDIR" -o ! -d "$LOGDIR" -o ! -w "$LOGDIR"
then
for LOGDIR in "`dirname $PARFILE`/logs/$p" $BUILDHOME/logs/$p \
/usr/tmp /var/tmp /tmp
do
test -d "$LOGDIR" || mkdir -p "$LOGDIR" 2> /dev/null
test -d "$LOGDIR" -a -w "$LOGDIR" && break
done
fi
msg="Check build logs for $p in `hostname`:$LOGDIR"
echo "$msg"
echo "$msg" | $MAIL -s "$msg" $USER 2> /dev/null
for u in $userhosts
do
build_one $u
done
done
# Limit exit status to common Unix practice
test $EXITCODE -gt 125 && EXITCODE=125
exit $EXITCODE
* * *
[2] Data elements and interchange formats—Information interchange—Representation of dates and times, available at http://www.iso.ch/cate/d26780.html. That standard writes dates in the form YYYY-MM-DDThh:mm:ss or YYYYMMDDThhmmss. The colons in the first form are undesirable in filenames for portability reasons, and the second form is hard for humans to read.
[3] See http://www.info-zip.org/.
[4] jar files can contain checksums and digital signatures that can be used to detect file corruption and tampering, so they may become popular for general software distribution.
[5] That certainly seems like a design flaw, since the underlying InfoZip format supports it.
[6] The Cathedral and the Bazaar: Musings on Linux and Open Source by an Accidental Revolutionary (O'Reilly).
Summary
In this chapter, we have written two useful tools that do not already exist on Unix systems, using shell statements and existing standard tools to carry out the task. Neither of them is particularly time-consuming to run, so there is little temptation to rewrite them in a programming language like C or C++. As shell scripts, they can be run without change on almost any modern Unix platform.
Both programs support command-line options, cleanly processed by while and case statements. Both use shell functions to simplify processing and prevent unnecessary code duplication. Both pay attention to security issues and perform sanity checks on their arguments and variables.
Chapter 9. Enough awk to Be Dangerous
The awk programming language was designed to simplify many common text processing tasks. In this chapter, we present a subset that suffices for most of the shell scripts that we use in this book.
For an extended treatment of the awk language,