#!/bin/bash #Copyright 2000 William Stearns #GPL'd, of course. #Version 0.2, 4/12/2000 #Usage: fanout "MACHINES" "commands and parameters to run on each machine" #Examples: # fanout "wstearns@localhost localhost anotherhost.someplace.net" \ # "echo My PID is \"\$PPID\" ; sleep 15" # # fanout "localhost" "uname -a ; rpm -qa | egrep -i '(openlinux|redhat-release)' \ # ; uptime ; df -P / ; netstat -a | grep '*:*'" | less # # fanout "localhost myaccount@localhost" "uptime" >uptime-sample # # ./fanout "$SERVERS $TEST" "uname -a ; ( if [ -f /var/log/dmesg ]; then \ # cat /var/log/dmesg ; else dmesg ; fi ) | egrep -i '(hd[a-h]|sd[a-h])' ; ls -al \ # /proc/kcore ; cat /proc/cpuinfo" >serverspecs # #Notes: #- The accounts you connect to should have your ssh key ready and you should be #running ssh-agent ready to serve that key. #- The command(s) you execute run concurrently on each remote machine. Output #does not show up until all are done. #- Sample run is at the end of the script. fanoutcleanup () { echo -n Exiting fanout, cleaning up... if [ -n "$OUTFILES" ]; then for ONEFILE in $OUTFILES ; do if [ -f $ONEFILE ]; then rm -f ONEFILE fi done fi echo done. exit } trap fanoutcleanup EXIT #Clean up on exit 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 if ! type -path mktemp >/dev/null 2>/dev/null ; then TMPFILE="/tmp/fanout.$MYPID.$ONETARGET" touch $TMPFILE else TMPFILE=`mktemp -q /tmp/fanout.XXXXXX` fi if [ $? -ne 0 ]; then echo "$0: Can't create temp file." else OUTFILES="$OUTFILES $TMPFILE" #Remember the filename for later display if 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 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 #Sample run #[wstearns@sparrow fanout]$ ./fanout "localhost wstearns@localhost aaa.bbb.ccc" "uptime" | less #aaa.bbb.ccc unavailable #Starting localhost #Starting wstearns@localhost #Fanout executing "uptime" #Start time Fri Apr 7 00:13:07 EDT 2000 , End time Fri Apr 7 00:13:20 EDT 2000 #==== On aaa.bbb.ccc ==== #==== Machine unreachable by ping # #==== On localhost ==== # 12:13am up 3 days, 10:44, 0 users, load average: 0.17, 0.17, 0.22 # #==== As wstearns on localhost ==== # 12:13am up 3 days, 10:44, 0 users, load average: 0.15, 0.16, 0.22