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

I am looking to store my output from router commands to an external file

open(DATA,"+>>default_ve.txt") || die "Couldn't open file , $!"; while (1) { my $content = $rh->cmd('show system processes extensive | match rp +d'); print DATA "$content"; }}

I see the file is getting created, but it does not have content . -rw-rw-r-- 1 user others 0 Nov 20 18:44 default_ve.txt Please let me know what iam missing here

Replies are listed 'Best First'.
Re: File operations
by GotToBTru (Prior) on Nov 20, 2015 at 13:28 UTC

    Are you sure there is anything in $content? One way to check would be to use the debugger.

    Update: as a general thing, simultaneous read and write access to a file gets messy. Also, not sure, but your use of DATA as the file handle might be causing trouble as well; it's a special word.

    use strict; use warnings; open my $fh,'>>','logname' or die "Could not open logname"; while (1) { my $content = $rh->cmd(...); if (defined $content) { print $fh $content } else { print 'Nothing to be done!' } sleep 1; } close $fh;
    Dum Spiro Spero
Re: File operations
by FloydATC (Deacon) on Nov 20, 2015 at 14:31 UTC
    Assuming $rh is connected to the appropriate host and you have successfully authenticated (to what looks like a Juniper device?), the main problem here seems to be your while(){} loop which will never end but (assuming ->cmd() ever exists) will keep executing the same command over and over, assigning the output to a variable that immediately goes out of lexical scope.

    Adding use strict; use warnings; would have pointed this out to you btw.

    Having worked quite a bit with Juniper devices myself, I used Net::Telnet::Cisco but had to customize the "prompt" setting in order to get ->cmd() to work as expected. If you are using that module and didn't set the appropriate "prompt" setting, then ->cmd() will hang indefinitely while waiting for a Cisco command prompt, which is a little different.

    I know I'm guessing a lot here, but I hope it helps. FYI, here's how I do it with MX, EX and SRX series -- seems to work pretty well:
    @lines = $session->cmd( String => 'show version | no-more', Prompt => '/\n\S+\>/');

    Putting it all together, try this:

    use strict; use warnings; # Open your $rh and authenticate here # ... open(my $fh, "+>>default_ve.txt") || die "Couldn't open file: $!"; my @lines = $rh->cmd(String => 'show version | no-more', Prompt => '/\ +n\S+\>/'); foreach my $line (@lines) { print $fh $line; } close $fh; # Close $rh or do more stuff here # ...

    Finally, note the use of "| no-more" to safeguard against output longer than your (virtual) terminal size which would cause an interactive prompt. Use it always, just to be safe.

    If you're not using a Juniper device, read the stuff about the loop and disregard everything else :o)

    -- FloydATC

    Time flies when you don't know what you're doing

Re: File operations
by toolic (Bishop) on Nov 20, 2015 at 13:41 UTC
    Maybe cmd is hanging.

    Other observations which are likely unrelated to your problem:

Re: File operations
by Eily (Monsignor) on Nov 20, 2015 at 13:34 UTC

    As GotToBTru said, it's probable $content doesn't contain anything. Isn't there a way to check if the command failed with whatever module you're using?

    Though here the problem probably isn't with the file, it can happen, and you can get that kind of information by checking the return value of print: print DATA $content or die "Couldn't write to file: $!";

Re: File operations
by mr_ron (Deacon) on Nov 21, 2015 at 14:41 UTC