Quoth "Peter J. Holzer" <
hjp-u...@hjp.at>:
> On 2012-01-21 17:35, Ben Morrow <
b...@morrow.me.uk> wrote:
> > Quoth "Peter J. Holzer" <
hjp-u...@hjp.at>:
> >> On 2012-01-17 11:46, Ben Morrow <
b...@morrow.me.uk> wrote:
> >> > Try system("ssh -f -L... ... sleep 10") instead of open3. It's important
> >> > with -f to use 'sleep 10' rather than -N, otherwise the ssh process will
> >> > never exit. (It doesn't seem to be very easy to find its pid to kill it
> >> > manually.)
> >>
> >> open($fh, '-|', ...) returns the pid, so does fork. The following script
> >> works for me, at least on linux:
> >
> > I think you're not realising what the -f argument to ssh does. It makes
> > ssh put itself in the background, but only after any possible need to
> > prompt the user has been dealt with.
>
> Yes, but there is no reason to use it. Perl can put processes in the
> "background" just fine. You will notice that my little test program
> doesn't use it.
Perl can put processes in the background just fine, yes. That's not the
issue. The issue is that sometimes ssh needs to prompt, and running it in
the background from Perl doesn't handle that very well.
I took the program you posted and made the following change:
@@ -16,7 +16,8 @@
$| = 1;
print "opening tunnel ... ";
my $pid = open(my $fh, '-|',
- 'ssh', '-N', 'h...@mri.DOMAIN', '-L', '10007:chronos.DOMAIN:7'
+ 'ssh', '-N', '-oUserKnownHostsFile=/dev/null',
+ 'isis', '-L', '10007:isis:7'
) or die;
print " done (pid=$pid)\n";
Apart from changing the host to one I have ssh access to, this sets
UserKnownHostsFile=/dev/null so ssh will always ask me to verify the
host key. If I run this, and I take more than 10 seconds to reply to the
prompt, the connection isn't set up properly and the program hangs
(script session wrapped for Usenet):
Script started on Sat Jan 21 20:28:55 2012
perl -x hjp-ssh
opening tunnel ... done (pid=49176)
The authenticity of host '
isis.morrow.me.uk (204.109.63.142)' can't
be established.
RSA key fingerprint is ee:8b:2a:da:6f:34:30:16:bf:84:85:50:f7:d6:7a:6f.
Are you sure you want to continue connecting (yes/no)? opening socket
... done
sending request ... Can't use an undefined value as a symbol reference
at hjp-ssh line 25.
^C
Script done on Sat Jan 21 20:29:40 2012
Obviously the 10 seconds' grace is a rather artificial feature of that
test program, and normally it would plough straight on without giving
the user any opportunity to respond.
If, instead, I make this change:
@@ -15,10 +15,12 @@
$| = 1;
print "opening tunnel ... ";
-my $pid = open(my $fh, '-|',
- 'ssh', '-N', 'h...@mri.DOMAIN', '-L', '10007:chronos.DOMAIN:7'
- ) or die;
-print " done (pid=$pid)\n";
+system(qw!
+ ssh -f -oUserKnownHostsFile=/dev/null
+ isis -L 10007:isis:7
+ sleep 10
+!) == 0 or die;
+print "ssh succeeded ... ";
sleep 5;
system('lsof', '-i', ':10007');
@@ -44,15 +46,7 @@
sleep(5);
system('lsof', '-i', ':10007');
-sleep(5);
-
-print "closing tunnel ... ";
-kill(15, $pid);
-my $rc = waitpid($pid, 0);
-print " done (rc = $rc)\n";
-sleep(5);
-system('lsof', '-i', ':10007');
__END__
hp
it will wait at the prompt until the user responds, and then continue
properly (I waited more than 10 seconds before typing 'yes'):
Script started on Sat Jan 21 20:29:55 2012
perl -x hjp-ssh-f
opening tunnel ... The authenticity of host '
isis.morrow.me.uk
(204.109.63.142)' can't be established.
RSA key fingerprint is ee:8b:2a:da:6f:34:30:16:bf:84:85:50:f7:d6:7a:6f.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '
isis.morrow.me.uk' (RSA) to the list of
known hosts.
ssh succeeded ... COMMAND PID USER FD TYPE DEVICE
SIZE/OFF NODE NAME
ssh 49204 mauzo 4u IPv6 0xffffff002c08b000 0t0 TCP
localhost:10007 (LISTEN)
ssh 49204 mauzo 5u IPv4 0xffffff002b228000 0t0 TCP
localhost:10007 (LISTEN)
opening socket ... done
sending request ... done
reading response ... channel 3: open failed: connect failed: Connection
refused
Use of uninitialized value $resp in concatenation (.) or string at
hjp-ssh-f line 31.
done (resp = )
closing socket ... done
Script done on Sat Jan 21 20:30:37 2012
It fails later, obviously, because there's nothing listening at the
remote end, but having failed both the Perl script and the ssh process
exit cleanly.
Ben