Reputation: 50
I am a newbie to perl.
my aim: executing telnet command and capturing full output
my code:
use IPC::Open2;
open2(\*RDR, \*WTR, "telnet host_name 8000 2>&1") or die ("could not contact host_name");
print WTR "$command\n";
print WTR "quit\n";
foreach my $line (<RDR>)
{
print $line."\n";
}
close RDR;
Problem: when executing the telnet command through putty, more than 12 lines of output is printed. But through this perl script only 3 lines are printed
Resolution attempts: I have tried Expect, Net::Telnet, IO::Pty. But due to security reasons these modules were not installed in my blade server.
Question: So, without using any of these helpful magic modules, how to get complete output of any telnet command using perl? Is there any restriction in number of characters in output buffer?
Upvotes: 1
Views: 319
Reputation: 66944
You didn't say anything about your $command
, but this works for me.
use warnings 'all';
use strict;
use IPC::Open2;
my $host = 'google.com';
my $pid = open2(\*RDR, \*WTR, "telnet $host 80 2>&1")
or die "Can't contact $host: $!";
print WTR "GET\n";
print WTR "quit\n";
while (my $line = <RDR>)
{
print $line if $. <= 10; # print only first 10 lines
}
close RDR;
waitpid($pid, 0);
my $child_exit_status = $? >> 8; # check how it went
This prints the whole page (without if ...
). Printing is limited to 10 lines for convenience.
Please read carefully through the documentation IPC::Open2 since all of this is involved.
open2()
returns the process ID of the child process. [...]
open2()
does not wait for and reap the child process after it exits. [...]
This whole affair is quite dangerous, as you may block forever. [...]
See also IPC::Open3. A well-regarded module is IPC::Run, if possible to have installed. Also excellent is Tiny::Capture, see a very similar problem with its use in this recent post. Both are very well known so perhaps your admins can accept them.
I suggest to switch to lexical filehandles
my $pid = open2 my $read_fh, my $write_fh, "telnet $host 80 2>&1"
or die "Can't contact $host: $!";
and change RDR
and WTR
throughout.
I don't know how Windows environment affects the above. The modules would give some confidence but I am not sure how open2
fares. Another possible culprit may be with buffering, even though I don't see how it would be in your code. Just in case, you can try
use IO::Handle;
STDERR->autoflush(1);
STDOUT->autoflush(1);
The IO::Handle
is loaded by default starting from, I think, v5.16.
There is also see a discussion on this in perlfaq5, with links for further reading.
However, if you do have a buffering problem it is most likely on the other end and that may not be easy to resolve without modules. To quote from Camel
As mentioned, the
IO::Pty
andExpect
modules provide a pseudo-tty device, giving you line-buffering without needing to modify the program on the end of the pipe.
Upvotes: 2