#!/bin/sh
#Copyright 2000, 2001, 2002, 2003 William Stearns <wstearns@pobox.com>
#GPL'd, of course.
#Version 0.6.1, 8/7/2002
#Home web site: http://www.stearns.org/fanout/
fanoutcleanup () {
echo -n Exiting fanout, cleaning up... >/dev/stderr
if [ -n "$OUTFILES" ]; then
for ONEFILE in $OUTFILES ; do
if [ -f $ONEFILE ]; then
rm -f ONEFILE
fi
done
fi
echo done. >/dev/stderr
exit
}
trap fanoutcleanup EXIT #Clean up on exit
usage () {
echo "Usage:" >/dev/stderr
echo " $0 \"MACHINES\" \"commands and parameters to run on each machine\"" >/dev/stderr
echo " $0 -h #Show this help" >/dev/stderr
echo " $0 --noping # Do not ping before running command" >/dev/stderr
echo >/dev/stderr
echo "Examples:" >/dev/stderr
echo " fanout \"wstearns@localhost localhost anotherhost.someplace.net\" \\" >/dev/stderr
echo " \"echo My PID is \\\"\$PPID\\\" ; sleep 15\"" >/dev/stderr
echo >/dev/stderr
echo " fanout \"localhost\" \"uname -a ; rpm -qa | egrep -i '(openlinux|redhat-release)' \\" >/dev/stderr
echo " ; uptime ; df -P / ; netstat -a | grep '*:*'\" | less" >/dev/stderr
echo >/dev/stderr
echo " fanout \"localhost myaccount@localhost\" \"uptime\" >uptime-sample" >/dev/stderr
echo >/dev/stderr
echo " If you set the SERVERS variable in your environment, you can run commands on" >/dev/stderr
echo " these machines over and over:" >/dev/stderr
echo >/dev/stderr
echo " export SERVERS=\"web1 web2 mail\"" >/dev/stderr
echo " fanout \"\$SERVERS \" \"uname -a ; ( if [ -f /var/log/dmesg ]; then \\" >/dev/stderr
echo " cat /var/log/dmesg ; else dmesg ; fi ) | egrep -i '(hd[a-h]|sd[a-h])' " >/dev/stderr
exit
}
if [ -z "$1" ]; then usage ; fi
if [ "$1" = "-h" ]; then usage ; fi
if [ "$1" = "--noping" ]; then PING="NO" ; shift ; fi
MYPID="$$"
TARGETS=`echo "$1" | tr ' ' '\012' | sort | uniq` #Sort and remove dupes
shift #Leave just the commands and params to be executed.
STARTTIME=`date`
for ONETARGET in $TARGETS ; do
case $ONETARGET in
*@*) #user@machine form
ONEUSER="-l ${ONETARGET%%@*}"
ONEMACH=${ONETARGET##*@}
HEADER="==== As ${ONETARGET%%@*} on $ONEMACH ===="
;;
*) #just machine form
ONEUSER=""
ONEMACH=$ONETARGET
HEADER="==== On $ONEMACH ===="
;;
esac
TMPFILE=`mktemp -q /tmp/fanout.XXXXXX`
if [ $? -ne 0 ]; then
echo "$0: Can't create temp file ${TMPFILE}." >/dev/stderr
exit 1
fi
OUTFILES="$OUTFILES $TMPFILE" #Remember the filename for later display, cleanup
if [ "$PING" = "NO" ] || ping -c 3 $ONEMACH >/dev/null 2>/dev/null ; then
echo Starting $ONETARGET >/dev/stderr #Machine is reachable
#Show machine name header, show command output, indented two spaces, save all to a temp file.
( echo $HEADER ; ssh -n $ONEUSER $ONEMACH "$*" | sed -e 's/^/ /' ; echo ) >$TMPFILE &
else
echo $ONETARGET unavailable >/dev/stderr #Machine not responding
echo $HEADER ; echo "==== Machine unreachable by ping" ; echo >$TMPFILE
fi
done
wait #Until everyone's done.
echo "Fanout executing \"$*\""
echo Start time $STARTTIME , End time `date`
for ONEFILE in $OUTFILES ; do
cat $ONEFILE
rm -f $ONEFILE
done
syntax highlighted by Code2HTML, v. 0.9.1