[Thamesvalley-pm] using ssh within perl scripts

Stephen Cardie stephenca at ls26.net
Wed Oct 31 05:07:57 PDT 2007

Greg Matthews wrote:
> [cut] 
> hope this makes sense and someone can point me the right direction


You can do this with IPC::Run.  A trivial example is shown below.  The 
@hosts data structure contains a list of hosts to interrogate; each 
element of this is a reference to a hash, the keys of which are 
hostname, username and cmds.  The last is an array of filename and 
command pairs, the command will be executed on the remote host and the 
output recorded in the file. Obviously, this could be the same for every 
host, in which case you'd remove if from the hash ref and just re-use 
the array for each host (i.e. call it @cmds and remove the line 
'my(@cmds) = @{$host->{cmds}};' below.

This is quite Expect-like, and, as has been suggested, you could achieve 
the same thing with Expect.pm, if you are more comfortable with that 

### BEGINS ####
use strict;
use warnings;

use IO::File;
use IPC::Run qw( start pump finish timeout );

my(@hosts) = (
     { hostname => 'myhost.mydomain.com',
       username => 'myusername',
       cmds     => [
           # Filename      Command
         [ 'uname_a.txt', "uname -a\n"],
         [ 'uname_s.txt', "uname -s\n"],

my($ssh_bin) = '/usr/bin/ssh';
my($ssh_opts) = '-2';

for my $host (@hosts) {
     my(@login) =
         ($ssh_bin, $ssh_opts, join '@' => @{$host}{qw(username hostname)});
     my(@cmds) = @{$host->{cmds}};

     $h = start( \@login, \$in, \$out, \$err, timeout( 3 ) );

     $in .= "\n";

     while (@cmds) {
         my($file,$cmd) = @{(shift @cmds)};
         $in .= $cmd;

         pump $h until ( $out=~/\n/ );
         my($fh) = IO::File->new($file, 'w');
         defined( $fh ) or die "Can\'t write to $file:$!";
         $fh->print( $out );
         $out = '';


#### ENDS #####

More information about the Thamesvalley-pm mailing list