Skip to content

Instantly share code, notes, and snippets.

@preaction
Created December 25, 2009 13:03
Show Gist options
  • Save preaction/263626 to your computer and use it in GitHub Desktop.
Save preaction/263626 to your computer and use it in GitHub Desktop.
autoplex.pl
# autoplex.pl
# Automatically run commands on multiple systems
# Licensed under the BSD or Artistic license (at users discretion)
# Copyright 2009 Doug Bell
# Usage:
# autoplex.pl -u <user> -p # Prompt for password once and use it for each server
# autoplex.pl -u <user> -P # Prompt for password every time
use strict;
use warnings;
# SSH wait timeout. Set this higher if you experience problems with
# timing commands
my $TIMEOUT = 10;
# A list of hostnames. Must be reachable by the current system
my @hosts = qw(
);
use Net::SSH::Expect;
use Term::ReadPassword qw(read_password);
use Getopt::Long qw(:config no_ignore_case);
my ( $pass_prompt_type, $user );
GetOptions(
'p' => sub { $pass_prompt_type = "once" },
'P' => sub { $pass_prompt_type = "every" },
'user|u:s' => \$user,
);
$user ||= $ENV{USER};
# Get the password once
my $password;
if ( $pass_prompt_type eq "once" ) {
$password = read_password( "Password: " );
}
for my $host ( @hosts ) {
my $ssh = Net::SSH::Expect->new(
host => $host,
raw_pty => 1,
);
unless ( $ssh->run_ssh ) {
warn "Couldn't start SSH: $!... Skipping $host\n";
next;
}
my $output;
$output = $ssh->peek($TIMEOUT);
if ( $output =~ /The authenticity of host/ ) {
$ssh->eat($ssh->peek(0));
$ssh->send("yes");
}
$output = $ssh->peek($TIMEOUT);
if ( $output =~ /(^.+?password:)\s*\z/im ) {
if ( $pass_prompt_type eq "every" ) {
$ssh->send( read_password( $1 ) );
}
else {
$ssh->send( $password );
}
}
# Try to find the command prompt
$output = $ssh->read_all($TIMEOUT);
unless ( $output =~ /[\$>#]\s*\z/ ) {
warn "Couldn't find prompt... Skipping $host\n";
print $output, "\n\n\n";
next;
}
### Do your real work here
}
sub get_output {
my ( $output ) = @_;
my @lines = split /\n/, $output;
pop @lines; # remove the prompt line
return join "\n", @lines[0..$#lines];
}
sub su {
my ( $ssh ) = @_;
$ssh->send("sudo su -");
$ssh->waitfor('Password:');
if ( $pass_prompt_type eq "every" ) {
$ssh->send( read_password( "Sudo password:" ) );
}
else {
$ssh->send( $password );
}
$ssh->send( $password );
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment