Galen has asked for the wisdom of the Perl Monks concerning the following question:

I have a small script that connects to a remote network element on a given port, issues a command, saves the results into an array using getlines, and then prints the data back to me. My problem (I think) is that the data is output with some very small delays that getlines seems to be interpreting as EOF. If I try to store the output in a single array, I get 17 lines. If I add a second getlines with a second array, I get an additional 21 lines. The third getlines grabs the last line, for a total of 39 lines. The problem is, the number of lines varies, and I can't keep just adding getlines and hoping that I get all the data. Why is getlines doing this? I've tried adding a Timeout to getlines, and to my initial open, but this does nothing. The pertinent lines are below, along with some of my debugging. Thanks for any suggestiions.
$connect = new Net::Telnet (Telnetmode => 0); $connect->open(Host => $hostname, Port => $port); $connect->print("$rtrv"); (@prematch,$match) = $connect->waitfor('/COMPLD/'); @rlines = $connect->getlines; @alines = $connect->getlines; @blines = $connect->getlines; print @rlines; print "\nShoud have all printed there...\n\n"; print @alines; print "\nAnd that was the second array\n\n"; print @blines; print "\n"; print "\nThat is the last of it\n\n";

Replies are listed 'Best First'.
Re: How do I tell getlines to get ALL the data?
by chipmunk (Parson) on Mar 22, 2001 at 02:13 UTC
    According to the docs for Net::Telnet, getlines() reads the next available lines from the remote host. If there are no lines available, it will wait until it times out. The behavior you're seeing is exactly as documented, so I'm not exactly sure what the difficulty is. Perhaps you want to call getlines() in a loop?
    $connect->print("$rtrv"); (@prematch,$match) = $connect->waitfor('/COMPLD/'); while (@lines = $connect->getlines(Timeout => 1)) { print "Got some lines:"; print @lines; }
      The problem is it doesn't seem to be waiting until it times out. It doesn't wait at all in fact. This is very odd, because if I implement a loop as you suggest, getlines does indeed gather all the lines of data, but the problem at that point is that it DOES time out, and I'm unable to execute the next command (logging off gracefully). I think if I rewrite the loop differently I might be able to get your approach to work. I should explain myself better. If you log directly into the element and issue the command manually, you get 39 lines of output in less than 1 second. There may be a tiny delay after groups of lines scroll by, but it's barely perceptible to the human eye. Apparently getlines is seeing it, however. It stops gathering data into the array and I am required to issue a new getlines to retrieve the rest of the data. This doesn't make sense to me, and it's even more confusing that when I loop it as you have shown above, I get a timeout after exactly as many seconds as specified (1 second in your example, 100 seconds if I change it to 100). So, timeout is working like this. But, if I just say:
      @lines = $connect->getlines(Timeout => 100);
      Then what I end up with is the first 17 lines out of 39 - every time. Changing the timeout has absolutely no effect. Weird huh?
        As I understood the documentation, the timeout is used only to wait for the first line of data. If there is already data waiting to be read, getlines returns those lines and returns immediately.