Appendix A. Contributed Scripts

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.