Beefy Boxes and Bandwidth Generously Provided by pair Networks Cowboy Neal with Hat
The stupid question is the question not asked
 
PerlMonks  

rcmd.pl

by greenFox (Vicar)
on Jul 25, 2002 at 12:26 UTC ( #185177=sourcecode: print w/ replies, xml ) Need Help??

Category: Utility Scripts
Author/Contact Info Murray Barton <muzza at iinet dot net dot au>
Description: rcmd.pl -a utility for running the same command across a group of hosts.
#!/usr/bin/perl -w
# 
# rcmd.pl
#
# run a command on multiple hosts!
# reads hosts from ~/rhosts
#
# if ~/rhosts is
#   host  group1,group3
#   host2  group2,group3
#   host3  group2
# then 
#  rcmd.pl -g group2 ls
# will run ls on host2 and host3
#
# great for run this command on "print hosts" or "solaris 8" machines 
+or
# red hat machines etc.
#
# Requires ssh installed- yeah I could have used Net:SSH, 
# not sure if that would any value though :)
#
# rcmd.pl started out as a quick and dirty one off 
# shell script and has grown...
#

use strict;
use Sys::Hostname;
use Getopt::Std;
my $home=get_home();
my %settings = (
          domain       => 'some.net.au',
          DEBUG        => 0,
          SSH          => "/usr/local/bin/ssh",
          SCP          => "/usr/local/bin/scp",
          HOST_FILE    => "$home/rhosts",
          runlocally   => 0,
        );

main_loop();
exit;

sub main_loop {

  my %args;
  getopts("g:hlnz", \%args);  # see print_help() for a description of 
+options
  print_help() and exit if $args{h};
  print_help() and exit if ! $args{g};
  my $host_group = $args{g} || '';
  my $no_prompt  = 1 if $args{n};
  my $no_errors  = 1 if $args{z};
  $settings{runlocally} = 1 if $args{l};
  print_help() and die "Specify command to run!\n" if ( ! scalar @ARGV
+);

  # the shell expands ~ and $home might be someplace different
  # on the destination host...
  my @command = map { s/^$home/~/; $_ } @ARGV;
  unshift @command, $settings{SSH};
  push @command, " 2>/dev/null" if $no_errors; 

  my @dest_hosts=get_hosts($settings{HOST_FILE}, $host_group);
  for my $host (@dest_hosts){
    unless ( $no_prompt ){
      print "Run @ARGV on $host [y/n]: ";
      chomp (my $answer = <STDIN>);
      next if ( $answer !~ /^y/i );
    }
    my @cmd = @command;
    splice(@cmd, 1, 0, $host);  # insert the hostname
    if ( $settings{runlocally} and $host eq $settings{localhost}){
      shift @cmd; shift @cmd;  # remove ssh and $hostname
    }
    print "Running [@cmd]\n" if $settings{DEBUG};
    my @result = `@cmd`;
    print "$host: ", @result, "\n";
  }
}

sub get_hosts {
  my $hosts_file = shift || die "sub get_hosts did not get a required 
+argument\n";
  my $host_group = shift || die "sub get_hosts did not get a required 
+argument\n";
  my $localhost = hostname();
  $localhost = (gethostbyname("$localhost.$settings{domain}"))[0] || $
+localhost;
  print "localhost: [$localhost]\n" if $settings{DEBUG};
  $settings{localhost} = $localhost;
  my @hosts;
  open (HOSTS, $hosts_file) || die "Could not open $hosts_file : $!\n"
+;
  while (<HOSTS>){
    next if /^\s*$/;
    next if /^\s*#/;
    chomp;
    my ($host, $groups) = split /\s+/;
    $host .= ".$settings{domain}" if ($host !~ /\./);
    my %groups = map { $_, 1 } split /,/, $groups;
    next if ( $host eq $localhost and ! $settings{runlocally});
    next if ( ! $groups{$host_group} and $host_group ne "all");
    print "Selecting [$host]\n" if $settings{DEBUG};
    push @hosts, $host;
  }  
  close(HOSTS);
  return @hosts;
}

sub get_home {
  my @pwd = getpwuid($<);
  my $home = $ENV{HOME} || $ENV{LOGDIR} || $pwd[7]
    or die "Could not determine home directory for $<";
  return $home;
}

sub print_help {
  print  "rput.pl -g <group> [options] file\n\n",
      "\twhere <group> is a group in your ~/rhosts file or \"all\"\n",
      "\t-h print this message\n",
      "\t-l run on local host\n",
      "\t-n no prompt just do it!\n",
      "\t-z suppres error messages\n";
}

Comment on rcmd.pl
Download Code

Back to Code Catacombs

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: sourcecode [id://185177]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (14)
As of 2014-04-16 16:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (432 votes), past polls