Hmm.
I'm not certain that I should post this here, but if not, please turn the
flamethrowers on 'medium'. The following is a bash script I wrote, because I
wanted to read the various documentation files in the /usr/src/linux hierarchy,
but I kept getting lost. It works other places, too, of course; I've been
installing stuff and found it useful for extracting the readable info from a
new package.
I'm posting it for two reasons: 1) someone else may find it mildly useful, and
2) I very much hope that some guru or gurus will point out where it can be
refined and debugged (it seems to run perfectly for me, but I didn't exactly
test it to destruction). It is a *bash* script, because I don't want to even
try to do the same thing without using some of bash's special builtins.
Note that it should be in the path. Although, come to think of it, changing
one line might fix that. ($(echo $0) instead of readyou where it calls itself
recursively). It also should be executable (you might could . it, I guess).
Comments, as I said, would be very welcome.
(about 200 lines follow--it looks like a few have wrapped; sorry)
#!/bin/bash
# readyou version 0.1
# readyou - a utility to locate the documentation files in a source tree
# and organize them in one place for easy reading.
# copyright 1995 Amy A. Lewis
# part one: parse the command line
# Another option to add: --diagnostics (-D?), which will explain what codes
# are assigned when we exit sloppily.
if [ "$readyousl" = "" ] ; then
export readyousl=$SHLVL
export incex=1
export incmake=1
sdir=.
ddir=$HOME"/srcdoc"
export ohshutup=1
export exts=' .c .h .in .o .orig .S .sh .shar .tar .tar.gz .tgz '
# Make sure that there's a leading and a trailing space, or the first/last
# test will fail! (Why? I dunno)
usage="
`basename $0` [-s source directory] [-d destination directory] [-D
--diagnostics
]
[-h --help] [--version] [-q --quiet] [-x] [-m] [-[+]e
ext[,.ext[,...]]]
If source directory is omitted, `basename $0` uses the current directory.
If destination directory is omitted, `basename $0` uses \$HOME/srcdoc.
-x includes executables, which are excluded by default.
-m includes 'Makefile's, which are excluded by default.
The -e parameter defines the extensions to exclude. It must be *last*.
If the option '+' is included, the extensions are added to the default list.
To see the default list, use -e alone. Note that the extensions must include
the period ('.') and must be separated by commas without white space.
All options must be separated by white space (-m -x is defined, -mx is not;
-s /src/dir is defined, -s/src/dir is not).
"
diag="
$(basename $0) returns 0 on a normal exit (this includes --help, --version, and
--diagnostics, and -e without a following extension, which are 'normal' exits).
1: Source directory unreadable, not specified, or nonexistent.
2: Destination directory unwritable, not specified, or nonexistent.
3: Required utilities not present.
"
fi
# we have to have certain utilities, or things will fail miserably.
# To do this, we use the bash builtin "type -type [name]" and we tell the
# user that there's a problem, and quit, if the return is anything but "file"
# we quit with a nasty little note. This is on the theory that
# the existence of an alias with the same name as a common program
# does not guarantee that the alias (or function) does the same thing.
# We need to have the following utilities: mkdir, cp, dirname, basename, sed.
# Do these tests even before parsing the command line, since we need sed and
# mkdir, at least, for them.
if [ $readyousl = $SHLVL ] ; then
for i in {mkdir,cp,dirname,basename,sed} ; do
if [ `type -type "$i"` != 'file' ] ; then
echo -n "$i is required to run this script, but does not exist or is an "
echo "alias or function--exiting." >&2
exit 3
fi
done
fi
while [ $# -ne 0 ] ; do
case "$1" in
-h | --help) echo "Usage: $usage" >&2 ; exit 0 ;;
--version) echo "readyou v. 0.1 -- (c) 1995 Amy Lewis" >&2 ; exit 0 ;;
-d)
shift
if [ $# -eq 0 ] ; then
echo "You must specify a directory with -d!" >&2
exit 2
fi
ddir=$1
shift ;;
-D | --diagnostics)
echo "Diagnostics: $diag"
exit 0 ;;
-e)
shift
if [ $# -eq 0 ] ; then
echo "Default extensions:$exts" >&2
echo "Use $(basename $0) -e .ext1,.ext2,.ext3,... to override
defaults."
>&2
echo "Use $(basename $0) -+e .ext1,.ext2,.ext3,... to add to defaults."
else
export exts=" $(echo $1 | sed -e 's/,/ /g') "
fi
shift ;;
-+e)
shift
if [ $# -ne 0 ] ; then
export exts="$exts $(echo $1 | sed -e 's/,/ /g') "
echo "$exts"
shift
fi ;;
-m)
export incmake=0
shift ;;
-s)
shift
if [ $# -eq 0 ] ; then
echo "You must specify a directory with -s!" >&2
exit 1
fi
sdir=$1
shift ;;
-q | --quiet)
export ohshutup=0
echo "Quiet!" >&2
shift ;;
-x)
export incex=0
shift ;;
*) echo "Usage: $usage" >&2 ; exit 0 ;;
esac
done
# Make sure the directories exist, and are readable/writable
if [ $readyousl -eq $SHLVL ] ; then
if [ ! -d $ddir ] ; then
if [ -e $ddir ] ; then
echo "$ddir already exists, and is not a directory. Exiting." >&2
exit 2
fi
mkdir -p $ddir
pushd $ddir >/dev/null
ddir=`echo $PWD`
popd >/dev/null
elif [ ! -w $ddir ] ; then
echo "You don't have write permission for $ddir. Exiting." >&2
exit 2
else
pushd $ddir >/dev/null
ddir=`echo $PWD`
popd >/dev/null
fi
if [ ! -d $sdir ] ; then
echo "$sdir does not exist, or is not a directory. Exiting." >&2
exit 1
elif [ ! -r $sdir ] ; then
echo "You don't have read permission for $sdir. Exiting." >&2
exit 1
fi
fi
# Now we actually get to the meat of the script.
# First, make certain that our $sdir holds something useful (it might have ".")
cd $sdir
sdir=`echo $PWD`
if [ $ohshutup -ne 0 ] ; then echo "Entering $sdir." ; fi
if [ $readyousl -eq $SHLVL ] ; then
if [ $ohshutup -ne 0 ] ; then echo "Destination directory: $ddir" ; fi
fi
# Hmm. We need to name our files intelligibly. But we don't want them
# to include the full path.
if [ $readyousl -eq $SHLVL ] ; then
bname=`basename $sdir`
else
cnt=$SHLVL
fqdirn=$sdir
bname=""
while [ $cnt -ne $readyousl ] ; do
bname="/"`basename $fqdirn`$bname
fqdirn=`dirname $fqdirn`
let $((cnt = cnt - 1))
done
bname=$(echo $bname | sed -e 's,/,.,g')
bname=${bname#.}
fi
# and add a trailing period
bname=$bname"."
# Note that if you use this script in / , the above will still give hidden
# files. Using "readyou -s .." won't, though.
nodirfiles=0
for fn in * ; do
if [ -d $fn ] ; then
if [ -r $fn ] ; then
readyou -s $sdir"/"$fn -d $ddir
else
echo "You don't have read permission for $fn, sorry. Skipping ..." >&2
fi
# if -e exists, pass it along too, of course. That's for later
elif [ -f $fn ] ; then
fqfn=$sdir"/"$fn
resext=1
if [ $incmake = 1 ] && [ "$fn" = "Makefile" ] ; then resext=0 ; fi
if [ $incex = 1 ] && [ -x $fn ] ; then resext=0 ; fi
dn=`dirname $fqfn`
# for re in {.c,.h,.in,.o,.orig,.S,.sh,.shar,.tar,.tar.gz,.tgz} ; do
for re in {$exts} ; do
if [ $resext = 1 ] ; then
bn=`basename $fqfn $re`
cf=$dn"/"$bn$re
if [ "$cf" = "$fqfn" ] ; then resext=0 ; fi
fi
done
if [ $resext = 1 ] ; then
cp $fn $ddir"/"$bname$fn
if [ $ohshutup -ne 0 ] ; then echo "Copying $fn to $ddir/$bname$fn" ; fi
let $((nodirfiles = nodirfiles + 1))
fi
else
echo "$fn is not a directory or a regular file, skipping ..." >&2
fi
done
echo "Exiting $sdir. $nodirfiles files copied.
"