Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling

Solution: Don't know why it works...

by cmv (Chaplain)
on Sep 21, 2009 at 18:42 UTC ( #796592=note: print w/replies, xml ) Need Help??

in reply to IO::Select & ssh problem


The following code seems to work between Sun_SSH_1.1.1 boxes. I don't know why it works, but it does. The secret ingredient was to add a system call that sent something to STDOUT before the system call (or exec) that does the ssh.

I'm guessing a bug in sshd on the target host. Any thoughts?



use strict; use warnings; use IO::Select; my $cmd = '"cat /etc/passwd"'; my $login = 'usr@host'; my $pkey = "$ENV{HOME}/.ssh/privateKey"; my @shell = ( '/usr/bin/ksh' => ( -c => "$cmd", )); my @sshcmd = ('/usr/bin/ssh' => ( -t => (), -i => $pkey, -o => 'StrictHostKeyChecking no', $login, @shell, )); if(my $child = open (IFILE, '-|')) { print STDERR "I'm the parent\n"; print STDERR "Child pid=$child\n"; }else{ select(STDIN); $|++; select(STDOUT); $|++; select(STDERR); $|++; print STDERR "I am the child\n"; print "LINE 1...\n"; print "LINE 2...\n"; print "LINE 3...\n"; print "LINE 4...\n"; my $ret; $ret = system('echo hi'); print STDERR "CHILD 1: ret=$ret\n"; $ret = system(@sshcmd); print STDERR "CHILD 2: ret=$ret\n"; print "LINE 5...\n"; print "LINE 6...\n"; print "LINE 7...\n"; print "LINE 8...\n"; } my $select = IO::Select->new(); $select->add(\*IFILE); my @ready; while ( @ready = $select->can_read(5) ) { foreach my $fh (@ready) { my $line = <$fh>; print STDERR "line=$line"; if(eof($fh)) { $select->remove($fh); close($fh) || warn "Close problem on fh: $fh"; } } } close(IFILE);

Replies are listed 'Best First'.
Re: Solution: Don't know why it works...
by ikegami (Pope) on Sep 21, 2009 at 18:47 UTC

    By the way, all your LINE lines are being printed to STDERR, since you made that handle the default using select.

    Easiest solution: replace

    select(STDIN); $|++; select(STDOUT); $|++; select(STDERR); $|++;
    use IO::Handle; STDOUT->autoflush(); STDERR->autoflush();
    or just
    $| = 1;

    It's useless to set autoflush on an input handle, and STDERR is already autoflushed.


      Thanks for pointing this out. I was casting around for anything that might help me, and it didn't occur to me what was actually happening.

      Although I was able to make the above script work, when I replaced the cat /etc/passwd line with a tail -f growingfile line, another problem occurred. The initial output from the tail comes out, but then nothing after that, even as I watch the file grow.

      I'm disappointed that I can't get this to work correctly, and can't figure out what is actually happening. If I can't make any progress today, I'll implement another method. Any suggestions would be appreciated.



Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://796592]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (5)
As of 2018-05-24 16:52 GMT
Find Nodes?
    Voting Booth?