#!/usr/bin/perl use warnings; use strict; use Net::SSH2; use Time::HiRes qw/gettimeofday/; my $cmd_timeout = 10; # In 250ms polls my $ssh = Net::SSH2->new(); $ssh->connect('HOSTNAME'); $ssh->auth_publickey('USER', 'KEYFILE.pub', 'KEYFILE') or die "auth failed: ".$ssh->error(); $ssh->blocking(1); my $channel = $ssh->channel() or die "channel failed: ".$ssh->error(); $channel->exec('(for i in $(seq 1 10); do sleep 1 && echo line number $i ; done)'); my @poll = ({handle => $channel, events => [qw/in ext/]}); $ssh->blocking(0); my $ttl = $cmd_timeout; my ($rv, %std); while (!$channel->eof()) { my $read = 0; $ssh->poll(500, [@poll]); my $buf; for my $poll (@poll) { print "got ", join(":", keys %{$poll->{revents}}), " poll events\n"; for my $ev (qw/in ext/) { next unless $poll->{revents}{$ev}; print "found event $ev\n"; if (my $r = $channel->read($buf, 8192, $ev eq 'ext')) { $read += $r; $std{$ev} .= $buf; } } } print "read is $read and ttl is $ttl and time is ", join(".", gettimeofday()), "\n"; if ($read) { $ttl = $cmd_timeout; } else { --$ttl; } if ($ttl < 1) { print "I got a timeout :(\n"; last; } } $channel->wait_closed(); $rv = $channel->exit_status(); $channel->close(); @std{qw/in ext/} = map { ($std{$_} || '') } qw/in ext/; print "in is $std{in} ext is $std{ext} rv is $rv\n"