Here's a handy tool I built, that uses rsh/rcp to distribute a given file to several hosts. See comments for explanation of voodoo magic.
#!/usr/bin/perl
##
## Push v0.1 written 030105:1209 by Bowie J. Poag
##
## This script pushes a given filename to all servers..if possible. :)
##
## Usage: push <filename> [destination_dir]
##
## This script requires certain conditions to be present in order to
## work correctly.
##
## First, all the hosts listed in the @hosts array must have their
## /.rhosts file configured to allow the host named in $distributorBox
## to perform rsh and rcp commands.
##
## Pick any box on you have access to. This box will act as your
## distributor box.
##
## The $distributorBox is the host responsible for passing out copies
## to the others. In this case, our distributorBox is named 'devo'.
##
## When this script is called, it first checks to see what host it's
## on. If it's being run from the distributor box, it will go ahead
## and pass out the file to the others. If the script sees that it's
## NOT on the distributor box, it will send a copy to the distributor,
## and then tell the distributor to pass it out. Kinda neat. :)
##
## This script should be kept in /usr/local/bin.
##
## To install this script network wide, simply push a copy of 'push':
##
## # /usr/local/bin/push /usr/local/bin/push /usr/local/bin
##
## :)
$distributorBox="devo"; # Set this to the box/IP address of your cho
+ice.
startupRoutine();
sanityCheck();
figureOutWhatToDoFirst();
spinDownRoutine();
sub startupRoutine()
{
$user=`whoami`;
$whereAmI=`hostname`; # $ENV{'HOSTNAME'} is non-ubiquitous in *nix.
chomp($user);
chomp($whereAmI);
@hosts=(
"moe",
"larry",
"shemp.nowhere.com",
"curly.norad.gov",
"shemp.org",
"joe",
"harpo.ee.ucsd.edu",
"zeppo",
"chico.net",
"gummo",
"groucho",
"karl", # Not a Marx brother, but still hilarious.
);
print "Push (on $whereAmI): Starting up..\n";
}
sub sanityCheck()
{
if ($#ARGV < 0 || $#ARGV > 1 || $user ne "root")
{
die(" Usage: $0 <filename> [location on remote host]\n\n Note
+: You must be root to use this command. If no target directory is gi
+ven, the name of the current directory is used. \n\
n");
}
$fileName=$ARGV[0];
chomp($targetPath=$ARGV[1] || `pwd`);
if(!$ARGV[1]) { print "Push (on $whereAmI): Warning -- Target path
+not specified. Assuming current directory..\n"; }
(-e $fileName) or die("Push (on $whereAmI): Eh? That file doesn't e
+xist here on $whereAmI.. Try again.\n\n");
$targetPath=~s'\/$''g; # Strip the trailing whack..
}
sub figureOutWhatToDoFirst()
{
if ($whereAmI eq $distributorBox)
{
pushRoutine();
}
else
{
$src="$fileName";
$trg="$distributorBox:$targetPath";
print "Push (on $whereAmI): Sending $fileName to $distributorBox
+ for distribution..\n";
system("rcp $src $trg");
system("rsh $distributorBox /usr/local/bin/push $fileName $targe
+tPath");
}
}
sub pushRoutine()
{
if ($whereAmI eq $distributorBox)
{
foreach $box (@hosts)
{
$src="$fileName";
$trg="$box:$targetPath";
print "Push (on $whereAmI): Sending $src from $whereAmI to $t
+rg..\n";
system("rcp $src $trg");
}
}
}
sub spinDownRoutine()
{
print "Push (on $whereAmI): Spinning down..\n";
exit; # bonk
}