views:

63

answers:

2

I have the following perl script that works locally given the input parameters. I need the script to access remote servers for the same information, given that I've already setup the ssh keys successfully. The path for the logfiles on the remote servers are identical to local. Configuration for remote servers are identical. I just need to run across multiple servers and bring back the data either to terminal or on a file. Do I need to put this in a shell script?

# usage example: <this script> Jun 26 2010 <logfile>
use strict;
use warnings;
my ($mon,$day,$year) = ($ARGV[0],$ARGV[1],$ARGV[2]);
open(FH,"< $ARGV[3]") or die "can't open log file $ARGV[3]: $!\n";
while (my $line = <FH>) {
    if ($line =~ /.* $mon $day \d{2}:\d{2}:\d{2} $year:.*(ERROR:|backup-date=|host=|backup-size=|backup-time=|backup-status)/) {
    print $line;
   }
}
+3  A: 

Provided your perl script is already in place on the remote servers, just invoke ssh someserver /path/to/the.script.pl. The remote stdout and stderr are piped back to you.

crazyscot
That will work. Thanks for you answer. :-)
jda6one9
+2  A: 

You could modify the script to take the server name as an extra argument.

# usage example: <this script> Jun 26 2010 <server> <logfile>
use strict;
use warnings;
my($mon,$day,$year,$server,$file) = @ARGV;
open(my $fh,"ssh $server cat $file |") or die "can't open log $server:$file: $!\n";
while (my $line = <$fh>) {
    if ($line =~ /.* $mon $day \d{2}:\d{2}:\d{2} $year:.*(ERROR:|backup-date=|host=|backup-size=|backup-time=|backup-status)/) {
    print $line;
   }
}

My version takes advantage of the fact that the Perl open function can 'open' a command and the output from the command is presented as input to your script.

---- edit

Regarding your follow-up question, if the file exists in the same place on a number of hosts then you could swap the argument order around and pass the list of hosts on the command-line:

# usage example: <this script> Jun 26 2010 <logfile> <server> ...
use strict;
use warnings;
my($mon,$day,$year,$file) = @ARGV;
splice(@ARGV, 0, 4, ());            # Discard first 4 args
foreach my $server ( @ARGV ) {
    open(my $fh,"ssh $server cat $file |") or die "can't open log $server:$file: $!\n";
    while (my $line = <$fh>) {
        if ($line =~ /.* $mon $day \d{2}:\d{2}:\d{2} $year:.*(ERROR:|backup-date=|host=|backup-size=|backup-time=|backup-status)/) {
            print $line;
        }
    }
    close($fh);
}
Grant McLean
Thanks Grant. I tested this. This works great! Say, I have a list of hosts, for example host1, host2, host3. What would be a clean way to pass all these at once? hostnames.txt:host1host2host3
jda6one9
@jaedre619 - see edit above
Grant McLean