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

Hello,

I want to capture the output of a command. I use IO::CaptureOutput. In simple programs, it works fine. As soon as I move it into a program running under CGI.pm 3.42, it does not work. See below for details.

use IO::CaptureOutput qw(qxy); ($output) = qxy(qw(/usr/local/bin/blaaaargh)); say "<blaaaargh failed: $output>";

Expected result:

<blaaaargh failed: /tmp/blaaaargh: Permission denied >
in the browser

Actual result:

<blaaaargh failed: >
in the browser
[Wed Nov 05 16:07:39 2008] [error] [client 127.0.0.1] /tmp/blaaaargh: +Permission denied
in the error_log

I also ran the CGI program from the command line with use CGI qw(:debug) and could verify that the error message comes first on STDERR, then comes the normal output on STDOUT (again, with the error message missing).

What do I do?

Replies are listed 'Best First'.
Re: capturing output fails under CGI
by MidLifeXis (Monsignor) on Nov 05, 2008 at 16:01 UTC

    Your CGI does not appear to be running as the same user as what your command line is using. Check your permissions on /tmp/blaaaargh, as the error suggests.

    Update: Your executable is sending stuff directly to stderr, which the error_log is capturing, but your IO::CaptureOutput object is not. My guess is that either IO::CO does not capture stderr, or you need to provide a flag to have it capture stderr.

    --MidLifeXis

      Or you need to explicitly tell the shell to redirect it to either a file (qx{zorble 2>/tmp/my_error.$$}) or to STDOUT (qx{blonk 2>&1}).

      The cake is a lie.
      The cake is a lie.
      The cake is a lie.

Re: capturing output fails under CGI
by ig (Vicar) on Nov 05, 2008 at 19:50 UTC

    Can you show code for a test case (as brief as possible) running under CGI that demonstrates the problem?

      I lied. Not on purpose, honest guv.

      The problem was the taint mode, not CGI.

      Also, I am stupid. Kids, your laugh for the day: I thought that local %ENV; localises it for the lexical scope (so it is automatically restored to its original contents after the block ends). But this statement also empties the hash!

      Thanks for the impulse, ig.