-
-
Save tbl3rd/6161384 to your computer and use it in GitHub Desktop.
When you can't get there from here ...
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /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' . " \\", | |
' [email protected]:2222 -N [email protected]' . " \\", | |
' -- 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