Skip to content

Instantly share code, notes, and snippets.

@tbl3rd
Created August 6, 2013 02:02
Show Gist options
  • Save tbl3rd/6161384 to your computer and use it in GitHub Desktop.
Save tbl3rd/6161384 to your computer and use it in GitHub Desktop.
When you can't get there from here ...
#! /opt/local/bin/perl -w
use strict;
use File::Basename;
# Return ssh with the standard command line options.
#
sub ssh {
my @result = qw(ssh -A -t);
push @result, qw(-o UserKnownHostsFile=/dev/null);
push @result, qw(-o StrictHostKeyChecking=no);
return @result;
}
# Show a usage message for $me and exit 1.
#
sub showUsage {
my ($me) = @_;
$me = basename $me;
my @usage =
("$me: Chain ssh commands through remote ssh servers with options.",
"Usage: $me [<options>] <remote> [[<options>] <remote> ...] [-- ...]");
my @where =
('Where: <options> are ssh options for <remote>',
' <remote> has syntax [<user>[:<pass>]@]<host>[:<port>]',
' <host> is the remote hostname passed to shh',
' <user> is an optional user name for authorization to <host>.',
' <pass> is an optional password passed to "sshpass -p" for
<user>',
' <port> is an optional integer port number for <host>',
' -- introduces optional command to run on last <remote>');
my @example =
('Example: ' . $me . ' root:password@somegateway' . " \\",
' root@172.21.139.28:2222 -N root@192.168.7.41' . " \\",
' -- ls -al',
'Runs: sshpass -p password ssh <standard-options>' . " \\",
' -l root somegateway ' . " \\",
' ssh <standard-options> -l root -p 2222 172.21.139.28' . " \\",
' ssh <standard-options> -N -l root 192.168.7.41 ls -al',
'Where: ssh <standard-options> ... is as shown below:');
my @lines = (@usage, @where, @example, join(' ', ssh, '...'));
print(STDERR "$_\n") for @lines;
exit 1;
}
# Return a hash parsed from 'user:pass@host:port'.
#
sub decodeHop {
my ($hop) = @_;
my %result = ();
if (0) {
} elsif ($hop =~ /^([^:@]+):(.+)@([^:@]+):(\d+)$/) {
@result{qw(user pass host port)} = ($1, $2, $3, $4);
} elsif ($hop =~ /^([^:@]+):(.+)@([^:@]+)$/) {
@result{qw(user pass host)} = ($1, $2, $3);
} elsif ($hop =~ /^([^:@]+)@([^:@]+):(\d+)$/) {
@result{qw(user host port)} = ($1, $2, $3);
} elsif ($hop =~ /^([^:@]+)@([^:@]+)$/) {
@result{qw(user host)} = ($1, $2);
} elsif ($hop =~ /^([^@]+)$/) {
@result{qw(host)} = ($1);
} else {
die "Cannot decodeHop '$_'";
}
return %result;
}
# Dump a hop hash returned by decodeHop().
#
sub dumpHop {
my %hop = @_;
my $sep = '{ ';
for (sort keys %hop) {
print $sep, $_, ' => ', $hop{$_};
$sep = ', ';
}
print ' }', "\n";
}
# Re-encode %hop with ssh command line options.
# Handle the password elsewhere.
#
sub encodeHop {
my %hop = @_;
my @result = ();
if ($hop{'user'}) {
push @result, '-l', $hop{'user'};
}
if ($hop{'port'}) {
push @result, '-p', $hop{'port'};
}
push @result, $hop{'host'};
return @result;
}
# Return an ssh command constructed from the arguments.
#
sub sshCommand {
my @result = ();
my @options = ();
my @rest = ();
for (@_) {
if (@rest || /^--/) {
push @rest, $_;
next;
} elsif (/^-/) {
push @options, $_;
next;
} else {
my %hop = decodeHop $_;
# dumpHop %hop;
my @hop = encodeHop %hop;
# print "HOP: @hop\n";
push(@result, qw(sshpass -p), $hop{'pass'}) if ($hop{'pass'});
push @result, ssh;
push @result, @options;
push @result, @hop;
@options = ();
}
}
push @result, @options;
shift @rest;
push @result, @rest;
return @result;
}
sub main {
if (@_) {
my @cmd = sshCommand @_;
print "RUN: @cmd\n";
system @cmd;
} else {
showUsage $0;
}
}
exit 0 if main @ARGV;
exit 1;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment