Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

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

Folks-

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?

Thanks

-Craig

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);


Comment on Solution: Don't know why it works...
Download Code
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); $|++;
    with
    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.

      ikegami++

      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.

      Thanks

      -Craig

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://796592]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (18)
As of 2015-07-30 20:56 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (273 votes), past polls