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

I'm having a bit of trouble debugging my perl....Whenever it prints out the problem, the output is too long for me to see in my command prompt. Now, before I get a lot of posts saying chop out pieces, debug it yourself, etc., I'm wondering: is there any way that I can make it output the bugs to a text file or something?

Thanks,
Spidy

Replies are listed 'Best First'.
Re: Debugging My Perl
by tachyon (Chancellor) on Sep 06, 2004 at 04:30 UTC
    perl script.pl 1>out 2>&1
    redirects STDOUT (1) and STDERR (2) to the file out.

    I am going to assume you are on Win32 in which case redirection of STDERR does not work. On old versions of Win32 redirection of STDERR does not work. Perhaps the easiest way to see all your errors is simply to increase the screen buffer of the (DOS) terminal window you are using to run your perl script. To increase the buffer, do this in a DOS window:

    • Right click on the title bar
    • Select Defaults
    • Select the Layout tab
    • In the Screen Buffer Size set the Height to say 500 (this will give you 500 lines of errors ;-) OK
    • Either apply it to just that window or all future DOS windows at the prompt OK

    Now you will have a scroll bar on the RHS of the DOS window and will be able to scroll back through hundreds of lines.

    Update

    Fixed incorrect statement as noted by BrowserUk and AM and changed syntax to one that works on Win32 and with Bash.

    cheers

    tachyon

      If you were on *nix you would probably already know how to do redirection like perl -e ' die' 2&> out where the 2&>out redirects STDERR (and STDOUT) to the file out.

      You forgot to mention that this works with Bourne shells only. Please don't assume that someone is using a Bourne shell -- or that they even have one. Some of us, in fact, despise Bourne shells, and avoid them at all cost.

        Next you're going to tell me you use emacs, not vi..... ;-)

        cheers

        tachyon

      Another way would be to install die() and warn() handlers in %SIG to log to a file. Localise them to just the bit of code that you're interested in:
      local $SIG{__DIE__} = sub { open LOGFILE, '>>logfile'; print LOGFILE 'die: ', @_; die("Died, errors logged to file\n"); } local $SIG{__WARN__} = sub { open LOGFILE, '>>logfile'; print LOGFILE 'warn: ', @_; close LOGFILE; }
      It may also be useful to log a timestamp for all die()s and warn()s, and spit out stack traces.
      I am going to assume you are on Win32 in which case redirection of STDERR does not work...

      Really?

      P:\test>perl -le"warn 'via STDERR'; print 'via STDOUT';" 1>junk 2>&1 P:\test>type junk via STDERR at -e line 1. via STDOUT P:\test>

      Examine what is said, not who speaks.
      "Efficiency is intelligent laziness." -David Dunham
      "Think for yourself!" - Abigail
      "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
      Apologies if I've misunderstood, but redirecting STDERR works fine on WinXP:

      perl script.pl 1>stdout.txt 2>stderr.txt
      ...Hmmm. I'm using windows 98. And while looking at the DOS title bar, I don't see a 'defaults'. Any other ideas?
Re: Debugging My Perl
by davido (Cardinal) on Sep 06, 2004 at 05:55 UTC

    How about putting this near the top of your script:

    BEGIN { open OLDERR, '>&STDERR' or die "Couldn't dupe STDERR.\n$!";; open STDERR, '>>', 'errors.log' or die "Couldn't redirect STDERR.\n$!"; print STDERR 'Starting run of $0 at ', scalar localtime, ", with parameters: @ARGV\n"; }

    Now OLDERR will preserve the original STDERR (for possible later use). And STDERR itself will be redirected to a file named 'errors.log'. I'm opening 'errors.log' in append mode, and prefacing each run with a timestamp. If you prefer standard write mode, use '>' instead of '>>'.

    That way, you'll be able to view errors.log with a regular text editor, or even a browser, which should solve the scrolling problem for you. Remember to remove this code, or disable it when the script is done being debugged. You don't want your errors.log file growing gigantic as a new entry is created in the file each time the script is run.


    Dave

      Alright, that worked. Thank you.
Re: Debugging My Perl
by Zaxo (Archbishop) on Sep 06, 2004 at 04:24 UTC

    In unix or winders, perl foo.pl > out.txt

    After Compline,
    Zaxo

Re: Debugging My Perl
by Old_Gray_Bear (Bishop) on Sep 06, 2004 at 04:36 UTC
    In Unix or Linux:
     perl my_program | more
    or
     perl my code | less

    I haven't needed to do development in a windows environment, so I don't know what the cognate is.

    In both environments:
     perl -d my_program

    ----
    I Go Back to Sleep, Now.

    OGB

      perl my_program | more

      This, surprisingly, works on Win32 (and DOS!) systems. Very good guess. :)

Re: Debugging My Perl
by uap (Novice) on Sep 06, 2004 at 05:46 UTC
    Somtimes i have this problem both in C++ and PERL. In PERL you could use the fact that you can redirect any print ng to screen to a file insteed. Create a filehandle tex. $myDebug = open(.... and switch screen to this file with select Example:
    ----------------------------------
    #!/usr/bin/perl

    use warnings;
    use strict;

    open (DEBUG, ">debug.txt") || die $!;

    print "Before redirecting to file\n";
    select DEBUG;

    print "This goes to de files\n";

    select STDOUT;

    print "And now we back\n";
    -------------------------------------

    // Anders
      Hmmm. I tried doing this, and apparently it DID print to the file, as the file now exists, but it says there is an error in permissions, and won't let me open it. Any ideas?
        Sorry i missed
        That you have to close the file, under Linux i could read the file anyway but i have hade troble with this under Windows, that a open file don't give you right to read.

        add Close as below example

        select STDOUT;
        close(DEBUG); # Close the debugfile
        print "And now we back\n";

        // Anders
Re: Debugging My Perl
by Popcorn Dave (Abbot) on Sep 06, 2004 at 17:30 UTC
    This may or may not be of help to you, but you might look in to the Perl/Tk Debugger here. It's saved my bacon any number of times and it will allow you to not have to print out "the problem" but watch your variables and how they're changing during execution.

    Hope that helps!

    Useless trivia: In the 2004 Las Vegas phone book there are approximately 28 pages of ads for massage, but almost 200 for lawyers.