7

I want to redirect the die messages to a separate file so that I can compare that file later to determine what went wrong.

But this code gives me errors:

$ cat test.pl
use strict;
use warnings;

my $log = "msglog.log";
die $log "DEAD$!";

$ perl test.pl
Missing comma after first argument to die function at test.pl line 5, near ""DEAD$!";"
Execution of test.pl aborted due to compilation errors.
$ 

I do not want to do a 2> from the caller. Is there someway to redirect them from within the script?

Axeman
  • 29,660
  • 2
  • 47
  • 102
Lazer
  • 90,700
  • 113
  • 281
  • 364

3 Answers3

15

You can install a $SIG{__DIE__} handler to be run just before the "die" runs. The handler will be called with the error message which you can log:

local $SIG{__DIE__} = sub {
    my ($message) = @_;
    # log the message        
};

See $SIG{expr} in perlvar for details.

Eugene Yarmash
  • 142,882
  • 41
  • 325
  • 378
10

Perl's die prints to STDERR so you could redirect STDERR to a file.

#!/usr/bin/env perl
# the path above depends on your system

open(STDERR, ">>", "errlog.log");
die "Hello";
rafl
  • 11,980
  • 2
  • 55
  • 77
wkl
  • 77,184
  • 16
  • 165
  • 176
  • 1
    This also redirects warn() messages, warnings, and anything else printed to STDERR. Not only that, if someone has done this properly by redefining the __DIE__ handler, it might not even redirect die() messages. – brian d foy Oct 15 '10 at 17:43
10

The Log::Log4perl module offers more than a few options.

One can choose to output the error message to both STDERR and the logfile.

my $logger = Log::Log4perl->init ( 'log.conf' );
# Configuration file controls what to output, like time, line number, class...

$logger->get_logger ( 'Hello::World' );  # Define which class logger to use

.
.
.

open my $fh, '<', $file
  or $logger->logdie ( "Log the demise: $!" );  # ... and die;

While it requires a little bit more effort in terms of setup, its flexibility unlocks a great deal of potential.

Zaid
  • 36,680
  • 16
  • 86
  • 155