These scripts, while not fitting into the text of this document, do illustrate some interesting shell programming techniques. They are useful, too. Have fun analyzing and running them.
Example A-1. manview: A script for viewing formatted man pages
| #!/bin/bash
# Formats the source of a man page for viewing in a user directory.
# This is useful when writing man page source and you want to
# look at the intermediate results on the fly while working on it.
if [ -z $1 ]
then
  echo "Usage: `basename $0` [filename]"
    exit 1
fi
groff -Tascii -man $1 | less
# From the man page for groff.
exit 0 | 
Example A-2. manview: A script for uploading to an ftp site, using a locally encrypted password
| #!/bin/bash # Example 3-71 modified to use encrypted password. if [ -z $1 ] then echo "Usage: `basename $0` filename" exit 1 fi Username=bozo # Change to suit. Filename=`basename $1` # Strips pathname out of file name Server="XXX" Directory="YYY" # Change above to actual server name & directory. password=`cruft <pword` # "pword" is the file containing encrypted password. # Uses the author's own "cruft" file encryption package, # based on onetime pad algorithm, # and obtainable from: # Primary-site: ftp://metalab.unc.edu /pub/Linux/utils/file # cruft-0.2.tar.gz [16k] ftp -n $Server <<End-Of-Session # -n option disables auto-logon user $Username $Password binary bell # Ring 'bell' after each file transfer cd $Directory put $Filename bye End-Of-Session exit 0 | 
+
The following two scripts are by Mark Moraes of the University of Toronto. See the enclosed file "Moraes-COPYRIGHT" for permissions and restrictions.
Example A-3. behead: A script for removing mail and news message headers
| #! /bin/sh # Strips off the header from a mail/News message i.e. till the first # empty line # Mark Moraes, University of Toronto # --> These comments added by author of HOWTO. if [ $# -eq 0 ]; then # --> If no command line args present, then works on file redirected to stdin. sed -e '1,/^$/d' -e '/^[ ]*$/d' # --> Delete empty lines and all lines until # --> first one beginning with white space. else # --> If command line args present, then work on files named. for i do sed -e '1,/^$/d' -e '/^[ ]*$/d' $i # --> Ditto, as above. done fi # --> Exercise for the reader: Add error checking and other options. # --> # --> Note that the small sed script repeats, except for the arg passed. # --> Does it make sense to embed it in a function? Why or why not? | 
Example A-4. ftpget: A script for downloading files via ftp
| #! /bin/sh 
# $Id: ftpget,v 1.2 91/05/07 21:15:43 moraes Exp $ 
# Script to perform batch anonymous ftp. Essentially converts a list of
# of command line arguments into input to ftp.
# Simple, and quick - written as a companion to ftplist 
# -h specifies the remote host (default prep.ai.mit.edu) 
# -d specifies the remote directory to cd to - you can provide a sequence 
# of -d options - they will be cd'ed to in turn. If the paths are relative, 
# make sure you get the sequence right. Be careful with relative paths - 
# there are far too many symlinks nowadays.  
# (default is the ftp login directory)
# -v turns on the verbose option of ftp, and shows all responses from the 
# ftp server.  
# -f remotefile[:localfile] gets the remote file into localfile 
# -m pattern does an mget with the specified pattern. Remember to quote 
# shell characters.  
# -c does a local cd to the specified directory
# For example, 
# 	ftpget -h expo.lcs.mit.edu -d contrib -f xplaces.shar:xplaces.sh \
#		-d ../pub/R3/fixes -c ~/fixes -m 'fix*' 
# will get xplaces.shar from ~ftp/contrib on expo.lcs.mit.edu, and put it in
# xplaces.sh in the current working directory, and get all fixes from
# ~ftp/pub/R3/fixes and put them in the ~/fixes directory. 
# Obviously, the sequence of the options is important, since the equivalent
# commands are executed by ftp in corresponding order
#
# Mark Moraes (moraes@csri.toronto.edu), Feb 1, 1989 
# --> Angle brackets changed to parens, so Docbook won't get indigestion.
#
# --> These comments added by author of HOWTO.
# PATH=/local/bin:/usr/ucb:/usr/bin:/bin
# export PATH
# --> Above 2 lines from original script probably superfluous.
TMPFILE=/tmp/ftp.$$
# --> Creates temp file, using process id of script ($$)
# --> to construct filename.
SITE=`domainname`.toronto.edu
# --> 'domainname' similar to 'hostname'
# --> May rewrite this to parameterize this for general use.
usage="Usage: $0 [-h remotehost] [-d remotedirectory]... [-f remfile:localfile]... \
		[-c localdirectory] [-m filepattern] [-v]"
ftpflags="-i -n"
verbflag=
set -f 		# So we can use globbing in -m
set x `getopt vh:d:c:m:f: $*`
if [ $? != 0 ]; then
	echo $usage
	exit 1
fi
shift
trap 'rm -f ${TMPFILE} ; exit' 0 1 2 3 15
echo "user anonymous ${USER-gnu}@${SITE} > ${TMPFILE}"
# --> Added quotes (recommended in complex echoes).
echo binary >> ${TMPFILE}
for i in $*
# --> Parse command line args.
do
	case $i in
	-v) verbflag=-v; echo hash >> ${TMPFILE}; shift;;
	-h) remhost=$2; shift 2;;
	-d) echo cd $2 >> ${TMPFILE}; 
	    if [ x${verbflag} != x ]; then
	        echo pwd >> ${TMPFILE};
	    fi;
	    shift 2;;
	-c) echo lcd $2 >> ${TMPFILE}; shift 2;;
	-m) echo mget "$2" >> ${TMPFILE}; shift 2;;
	-f) f1=`expr "$2" : "\([^:]*\).*"`; f2=`expr "$2" : "[^:]*:\(.*\)"`;
	    echo get ${f1} ${f2} >> ${TMPFILE}; shift 2;;
	--) shift; break;;
	esac
done
if [ $# -ne 0 ]; then
	echo $usage
	exit 2
fi
if [ x${verbflag} != x ]; then
	ftpflags="${ftpflags} -v"
fi
if [ x${remhost} = x ]; then
	remhost=prep.ai.mit.edu
	# --> Rewrite to match your favorite ftp site.
fi
echo quit >> ${TMPFILE}
# --> All commands saved in tempfile.
ftp ${ftpflags} ${remhost} < ${TMPFILE}
# --> Now, tempfile batch processed by ftp.
rm -f ${TMPFILE}
# --> Finally, tempfile deleted (you may wish to copy it to a logfile).
# --> Exercises for reader:
# --> 1) Add error checking.
# --> 2) Add bells & whistles. |