116 lines
2.5 KiB
Bash
116 lines
2.5 KiB
Bash
#! /bin/sh
|
|
#
|
|
# descend - walk down a directory tree and execute a command at each node
|
|
|
|
fullname=$0
|
|
name=descend
|
|
usage="Usage: $name [-afqrv] command [directory ...]\n
|
|
\040\040-a\040\040All: descend into directories starting with '.'\n
|
|
\040\040-f\040\040Force: ignore errors during descent\n
|
|
\040\040-q\040\040Quiet: don't print directory names\n
|
|
\040\040-r\040\040Restricted: don't descend into RCS, CVS.adm, SCCS directories\n
|
|
\040\040-v\040\040Verbose: print command before executing it"
|
|
|
|
# Scan for options
|
|
while getopts afqrv option; do
|
|
case $option in
|
|
a)
|
|
alldirs=$option
|
|
options=$options" "-$option
|
|
;;
|
|
f)
|
|
force=$option
|
|
options=$options" "-$option
|
|
;;
|
|
q)
|
|
verbose=
|
|
quiet=$option
|
|
options=$options" "-$option
|
|
;;
|
|
r)
|
|
restricted=$option
|
|
options=$options" "-$option
|
|
;;
|
|
v)
|
|
verbose=$option
|
|
quiet=
|
|
options=$options" "-$option
|
|
;;
|
|
\?)
|
|
/usr/5bin/echo $usage 1>&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
shift `expr $OPTIND - 1`
|
|
|
|
# Get command to execute
|
|
if [ $# -lt 1 ] ; then
|
|
/usr/5bin/echo $usage 1>&2
|
|
exit 1
|
|
else
|
|
command=$1
|
|
shift
|
|
fi
|
|
|
|
# If no directory specified, use '.'
|
|
if [ $# -lt 1 ] ; then
|
|
default_dir=.
|
|
fi
|
|
|
|
# For each directory specified
|
|
for dir in $default_dir "$@" ; do
|
|
|
|
# Spawn sub-shell so we return to starting directory afterward
|
|
(cd $dir
|
|
|
|
# Execute specified command
|
|
if [ -z "$quiet" ] ; then
|
|
echo In directory `hostname`:`pwd`
|
|
fi
|
|
if [ -n "$verbose" ] ; then
|
|
echo $command
|
|
fi
|
|
eval "$command" || if [ -z "$force" ] ; then exit 1; fi
|
|
|
|
# Collect dot file names if necessary
|
|
if [ -n "$alldirs" ] ; then
|
|
dotfiles=.*
|
|
else
|
|
dotfiles=
|
|
fi
|
|
|
|
# For each file in current directory
|
|
for file in $dotfiles * ; do
|
|
|
|
# Skip '.' and '..'
|
|
if [ "$file" = "." -o "$file" = ".." ] ; then
|
|
continue
|
|
fi
|
|
|
|
# If a directory but not a symbolic link
|
|
if [ -d "$file" -a ! -h "$file" ] ; then
|
|
|
|
# If not skipping this type of directory
|
|
if [ \( "$file" != "RCS" -a \
|
|
"$file" != "SCCS" -a \
|
|
"$file" != "CVS" -a \
|
|
"$file" != "CVS.adm" \) \
|
|
-o -z "$restricted" ] ; then
|
|
|
|
# Recursively descend into it
|
|
$fullname $options "$command" "$file" \
|
|
|| if [ -z "$force" ] ; then exit 1; fi
|
|
fi
|
|
|
|
# Else if a directory AND a symbolic link
|
|
elif [ -d "$file" -a -h "$file" ] ; then
|
|
|
|
if [ -z "$quiet" ] ; then
|
|
echo In directory `hostname`:`pwd`/$file: symbolic link: skipping
|
|
fi
|
|
fi
|
|
done
|
|
) || if [ -z "$force" ] ; then exit 1; fi
|
|
done
|