Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

How does one redirect STDERR to a file? ((Filehandle, redirection, logging))

by princepawn (Parson)
on Sep 26, 2000 at 23:16 UTC ( [id://34088]=perlquestion: print w/replies, xml ) Need Help??

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

I am using Net::FTP, but some people using it are getting timeouts and other failures. I want to enable debugging when creating Net::FTP sessions, but Net::FTP logs to STDERR.

I was hoping to take STDERR and save it in a file and then FTP it to myself to save the person using my script the trouble.

I want to control the redirection of STDERR to a file via my Perl program, because I cant ensure that the people using my program will reliably use the proper unix notation to do this.

  • Comment on How does one redirect STDERR to a file? ((Filehandle, redirection, logging))

Replies are listed 'Best First'.
(jcwren) Re: How does one redirect STDERR to a file? ((Filehandle
by jcwren (Prior) on Sep 27, 2000 at 00:17 UTC
    This worked for me...
    #!/usr/local/bin/perl -w use strict; use Net::FTP; { open (FH, ">debug") || die $!; *STDERR = *FH; my $ftp = Net::FTP->new ("linux", Debug => 1) || die $!; $ftp->login ("foo", "bar"); $ftp->quit; close (FH); }
    --Chris

    e-mail jcwren
Re: How does one redirect STDERR to a file? ((Filehandle
by Fastolfe (Vicar) on Sep 26, 2000 at 23:20 UTC
    Redirect STDERR into a log file as the first thing your script does. Unfortunately, it's likely some module compile-time errors will go un-seen as a result, and get bumped into this stderr.log. Be sure to take a look there when you're debugging problems.
    BEGIN { open(STDERR, ">stderr.log"); }
      That probably wanted to be :-
      BEGIN { open(STDERR, ">>stderr.log") or die "Failed to open log file"; }
      Note the >> and the or die.

      You could do this with a tied file handle too, as demonstrated recently by tilly - here

Re: How does one redirect STDERR to a file? ((Filehandle
by chromatic (Archbishop) on Sep 27, 2000 at 00:20 UTC
    An answer that uses fork. I wouldn't use this -- I'd make a shell alias that does the redirection for the users. I'm lazy that way.
    #!/usr/bin/perl -w use strict; use POSIX ":sys_wait_h"; BEGIN { open(STDERR, ">>stderr.log") or die "Bad, can't open log: $!"; } die "Can't fork!" unless (defined(my $pid = fork())); if ($pid) { my $kid; do { $kid = waitpid(-1, &WNOHANG); } until $kid == -1; } else { exec "./realprog.pl"; }
Re (tilly) 1: How does one redirect STDERR to a file? ((Filehandle
by tilly (Archbishop) on Sep 27, 2000 at 01:48 UTC
    I am feeling silly, so try this:
    # Takes a filehandle and filename and has output to that handle go # to STDERR and to that filename. It will work even if the handle # being tied is STDERR itself. No escaping is done for the filename, # caveat programmer sub tee_to_stderr { my $file = shift || die "No filename passed\n"; my $ip = open (STDERR, "| perl") || die "Cannot pipe to Perl: $!"; my $fh = select(STDERR); $| = 1; select($fh); print STDERR qq( unless(open (OUT, ">$file")) { print STDERR "Cannot write to $file: \$!\n"; kill 9, getppid(); } select(STDERR); \$| = 1; select(OUT); \$| = 1; while (<>) { print OUT; print STDERR; } ); print STDERR "\n__END__\n"; }
    (The attempt to kill the parent won't work in Windows, otherwise this gives you one very convoluted way to do something that should be simple.)

    The idea is to not just redirect STDERR, but also to have it still going to STDERR so that you get your log and they still see their own errors.

    The right way to do this should use IO::Tee, but the problem is that one of the filehandles you want to tee is STDERR. This gets us into the same recursion that you saw in Filehandle Filter. I don't have the energy at the moment to offer a good solution, though I am sure there is one and that I will be very irritated with myself when I see it...

    UPDATE
    I am indeed irritated. Fastolfe pointed out that you can always dup a filehandle:

    open(NEW, ">&OLD") or die "Cannot dup OLD: $!";
    So dup STDERR, then proceed to do what you want.
RE: How does one redirect STDERR to a file? ((Filehandle, redirection, logging))
by myocom (Deacon) on Sep 27, 2000 at 00:23 UTC

    Sometimes it's easier to let the shell work for you. Have you considered writing a shell script that neatly wraps up the 2>stderr.log?

    ObFastolfeDisclaimer: You may want to use 2>>stderr.log instead.

      Thats a bit difficult in this case because I would have to propagate command-line arguments from the wrapper to the real script.... ACtually maybe not:
      @syscmd = ('real-prog', @ARGV); system @syscmd or die "syscmd failed";

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://34088]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (6)
As of 2024-04-25 15:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found