ssh ssh

J

jammer

I am trying to write a script that takes a list of hosts and sshs into
the first one and then can ssh to other ones. I can only ssh to the
other hosts from the first host.

Here is what I tried:
I think it is waiting for the ssh to the first host to finish.

I guess I could scp a partial hostlist and a program to *.domain and
then run the program remotely.
Am I on a right track?

#!/bin/perl

use strict;

open( HL, '<hostlist3.txt' ) || die "can't open hostlist3";
#!/bin/perl

use strict;

open( HL, '<hostlist3.txt' ) || die "can't open hostlist3";

my $newCC;
my $line;

while ($line = <HL>) {
chop $line;

if ($line eq '') {
$newCC = 1;
}

if ($newCC == 1) {
if ($line ne '') {
$newCC = 0;
print "ssh $line\n";

# print `ssh $line`;
}
} else {
print "ssh $line uname -a\n";

# print`ssh $line uname -a`;
}
}

close( HL );

For example, if hostlist3.txt contains:

host1.domain
host2

host3.domain
host4

I need to ssh into host1.domain to ssh to host2
Then I need to ssh to host3.domain ro ssh to host4

The goal is to run 'uname' on a bunch of machines that are only
accessible from the *.domain machine.
The machine running the program can access all the *.domain machines
but not the others.
 
B

Ben Morrow

Quoth jammer said:
I am trying to write a script that takes a list of hosts and sshs into
the first one and then can ssh to other ones. I can only ssh to the
other hosts from the first host.

Here is what I tried:
I think it is waiting for the ssh to the first host to finish.

I guess I could scp a partial hostlist and a program to *.domain and
then run the program remotely.
Am I on a right track?

No. Step back a minute and consider how you would do this without Perl:
what you want to end up running is

ssh host1.domain ssh host2 uname -a

assuming ssh is in your default PATH on host1.domain. What you actually
end up running, here (or would if it weren't commented),
# print `ssh $line`;

is

ssh host1.domain

with no command specified. This will give you a shell; while it would be
possible to remote-control that shell, it's much easier to use ssh's
ability to run a command directly. You want something like

open my $HOSTLIST, '<', 'hostlist3.txt'
or die "can't open hostlist3.txt: $!";

$/ = ''; # this will read a paragraph at a time
$\ = "\n"; # avoids needing to print it all the time

while (<$HOSTLIST>) {
my $cmd = join ' ', map "ssh $_", split /\n/;
$cmd .= ' uname -a';
print "executing '$cmd'";
print `$cmd`;
}

which will cope with any number of intervening hosts automatically. Note
that this assumes none of the items in hostlist3.txt have spaces in:
annoyingly, there isn't a form of backticks corresponding to system
LIST, so that would be rather harder to deal with.

Ben
 
J

jammer

No. Step back a minute and consider how you would do this without Perl:
what you want to end up running is

ssh host1.domain ssh host2 uname -a

assuming ssh is in your default PATH on host1.domain. What you actually
end up running, here (or would if it weren't commented),


is

ssh host1.domain

with no command specified. This will give you a shell; while it would be
possible to remote-control that shell, it's much easier to use ssh's
ability to run a command directly. You want something like

open my $HOSTLIST, '<', 'hostlist3.txt'
or die "can't open hostlist3.txt: $!";

$/ = ''; # this will read a paragraph at a time
$\ = "\n"; # avoids needing to print it all the time

while (<$HOSTLIST>) {
my $cmd = join ' ', map "ssh $_", split /\n/;
$cmd .= ' uname -a';
print "executing '$cmd'";
print `$cmd`;
}

which will cope with any number of intervening hosts automatically. Note
that this assumes none of the items in hostlist3.txt have spaces in:
annoyingly, there isn't a form of backticks corresponding to system
LIST, so that would be rather harder to deal with.

Ben

Here is my next attempt:

#!/bin/perl

use strict;

my $inputFile = 'hostlist3.txt';

open my $HOSTLIST, '<', $inputFile
or die "can't open hostlist: $!";

$/ = ''; # this will read a paragraph at a time
$\ = "\n"; # avoids needing to print it all the time

while (<$HOSTLIST>) {
my @hostList = split /\n/;

my $adminHost = shift( @hostList ); # first line

print 'adminHost=' . $adminHost;

my $otherHosts = join ' ', map "ssh $_ uname -a", @hostList;

my $cmd = "ssh ccn\@$adminHost $otherHosts";

print "executing '$cmd'";
print `$cmd`;
}

The problem is that I can't seem to run more than one command from
ssh.
I don't really want to open and ssh connection for each otherHosts.

What if hostlist3.txt is:
host1.domain
host2
host3

host4.domain
....

I need 'ssh host1.domain ssh host2 uname -a ssh host3 uname -a'.
I can do 'ssh host1.domain ssh host2 uname -a' and 'ssh host1.domain
ssh host3 uname -a' but I'd rather not ssh to host1.domain more than
once.
 
J

Josef Moellers

jammer said:
I am trying to write a script that takes a list of hosts and sshs into
the first one and then can ssh to other ones. I can only ssh to the
other hosts from the first host.

IIUC you want to ssh to one host, then, from that host, ssh to another
host, from there on ssh to yet another host ...

You might want to look at Expect. I've used it to repeatedly log into a
remote host via a pretty complex series of internal and external hosts
which, in part, perform callbacks for security reasons.
 
P

Peter J. Holzer

Here is my next attempt:

#!/bin/perl

use strict;

my $inputFile = 'hostlist3.txt';

open my $HOSTLIST, '<', $inputFile
or die "can't open hostlist: $!";

$/ = ''; # this will read a paragraph at a time
$\ = "\n"; # avoids needing to print it all the time

while (<$HOSTLIST>) {
my @hostList = split /\n/;

my $adminHost = shift( @hostList ); # first line

print 'adminHost=' . $adminHost;

my $otherHosts = join ' ', map "ssh $_ uname -a", @hostList;

That doesn't look right.
my $cmd = "ssh ccn\@$adminHost $otherHosts";

print "executing '$cmd'";
print `$cmd`;
}

The problem is that I can't seem to run more than one command from
ssh.
I don't really want to open and ssh connection for each otherHosts.

What if hostlist3.txt is:
host1.domain
host2
host3

host4.domain
...

I need 'ssh host1.domain ssh host2 uname -a ssh host3 uname -a'.

No, you don't.

ssh host2 uname -a ssh host3 uname -a

is not the command you want to execute on host1.domain. Maybe you want
to execute

ssh host2 uname -a; ssh host3 uname -a

hp
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,736
Latest member
AdolphBig6

Latest Threads

Top