in reply to how i capture a script error to a file ?

The error is not passed as an argument to your die handler, but is in $@.

Why shell out just to print an error message?

my $message = $@; if( open my $log, '>>', 'log.err' ) { print $log $message; } else { warn "Couldn't write to 'log.err': $!"; warn $message; };

Also, your __DIE__ handler will also be invoked from within eval { ... } blocks, which is most likely only confusing to you. You should check $^S to see if eval is currently running:

return if $^S; # we are within an eval block

Replies are listed 'Best First'.
Re^2: how i capture a script error to a file ?
by shmem (Chancellor) on Apr 27, 2017 at 13:16 UTC
    The error is not passed as an argument to your die handler, but is in $@.

    How so? $@ is the last eval error. The arguments to die are passed to the DIE handler (whether invoked by perl itself or via die):

    local $SIG{__DIE__} = sub { open my $fh, '>>', 'log.err' or warn "Can't append to 'log.err': $!" and return; print $fh @_, "\n\$\@: |$@|"; }; eval { die "fubar!"; }; # <--- update, semicolon was missing 1 / 0; __END__ Illegal division by zero at foo.pl line 8.

    Contents of log.err:

    @_: |fubar! at foo.pl line 7. | $@: || @_: |Illegal division by zero at foo.pl line 8. | $@: |fubar! at foo.pl line 7. |

    The fubar! at foo.pl line 7. is repeated since $@ hasn't been cleared. If there had been a subsequent succeeding eval, $@ had been cleared.

    Neither die messages nor system errors ($!) are shoehorned into $@ for the DIE handler.

    update 2:

    Also, your __DIE__ handler will also be invoked from within eval { ... } blocks, which is most likely only confusing to you. You should check $^S to see if eval is currently running:
    return if $^S; # we are within an eval block

    This, as a general advice, is misleading. One might very well be interested in eval errors.

    perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
      eval dont work on me :(
      Number found where operator expected at ./test3.pl line 21, near "1" (Missing semicolon on previous line?) syntax error at ./test3.pl line 21, near "1" Execution of ./test3.pl aborted due to compilation errors.

        Missing ; after the eval { } , corrected. Sorry. We all write our own bugs :-(

        perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'