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

I have a CGI that contains the following call:
my $scale = `/www/2cgi-bin/res2.pl $file`;

res2.pl contains this:

die "No parameters given" unless $img = $ARGV[0];
...and others 'die' commands. The problem is that $scale doesn't get the die reason. Is there another way than putting a "print diereason then die"?

Replies are listed 'Best First'.
RE: How may I know why it died?
by gryng (Hermit) on Jul 15, 2000 at 02:38 UTC
    die will print to your STDERR, not STDOUT, so you need to be checking that in your CGI file. You could use a quick fix such as:
    my $scale = `/www/2cgi-bin/res2.pl $file 2>&1`
    (hopefully I got that syntax correct, I don't have access to my trusty unix boxes right now).

    However there are probably better ways than what I can remember off the top of my head.

    Sorry, but good luck,
    Gryn

    Updated: Fixed typo as suggested by nardo (thanks :) ).

      2&>1 should be 2>&1
RE: How may I know why it died?
by Adam (Vicar) on Jul 15, 2000 at 02:47 UTC
    back ticks only return STDOUT from the system call, but they do set $? to the call's error status. So at least your script can know that the call failed (and if you control res2.pl you can have it exit($errorstate) where $errorstate is specific to the cause of the problem, or even $! )
    And of course, $! is often the error message (but not always)
      You cannot rely on the $! containing anything useful if a child process has set it and died. It sometimes happens, but there's nothing that garantees this. And it's very unportable.

      And $? will contain whatever exit value the spawned program returned. This may be non-zero in the case of an error - but that is only a convention, not law. And programs can issue warnings on stderr, while completing a task succesfully.

      Just use IPC::Open3.

      -- Abigail

(chromatic) Re: How may I know why it died?
by chromatic (Archbishop) on Jul 15, 2000 at 06:32 UTC
    The CGI::Carp module might come in handy here. Put the following near the top to trap die exceptions: use CGI::Carp qw(fatalsToBrowser); I wouldn't run this in production code, as it could give out information a malicious cracker might be able to exploit.

    Update: Okay, it might not. Win some, lose others.

      The CGI::Carp module might come in handy here.

      I don't think so. CGI::Carp masks die, warn and friends. And while it has a method to redirect STDERR to a file, it doesn't hand you the errors of spawned sub processes.

      However, the standard distribution of Perl comes with IPC::Open3, which allows you to give it a filehandle that will be connected to the spawned processes' stderr. One can than just read from this handle and capture any errors. Note that you might have to use IO::Select to avoid blocking problems. Read the man page of IPC::Open3.

      -- Abigail