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

Can anyone tell me why I'm unable to capture STDERR in a filehandle using the following snippet?
my $key = $buttons->Button( -text => $key, -width => '10', -command => sub { my $cmd = $button{$prog}{$key}; $pid = open(ERROR, "$cmd 2>&1 1>/dev/null |"); while (<ERROR>) { print "ERROR: $_\n"; } } )->pack(-side => 'top', -pady=>'10');
When the sub routine is called the STDERR is bypassed and printed directly to the screen.

Replies are listed 'Best First'.
Re: Sending STDERR to a filehandle
by Mr. Muskrat (Canon) on Jun 09, 2003 at 17:54 UTC
    You are redirecting STDERR to STDOUT with '2>&1' and you're sending the STDOUT from the command to /dev/null with '1>/dev/null'. You then print each line of output from the command to STDOUT (which now will be the STDERR of the command) in the while loop.

      I think you may have misunderstood his intentions. He wants to discard the usual stdout of the program and read its usual stderr via the pipe. He is doing that by duping stderr to stdout and redirecting stdout to /dev/null. The way he has it should work.

      -sauoq
      "My two cents aren't worth a dime.";
      
      Thats my problem, it's not making it into the while loop.
        Are you sure? Try this on for size:
        my $cmd = q(perl -e 'die'); my $pid = open(ERROR, "$cmd 2>&1 1>/dev/null |"); print "$pid\n"; while (<ERROR>) { print "ERROR: $_\n"; }
Re: Sending STDERR to a filehandle
by bobn (Chaplain) on Jun 09, 2003 at 21:02 UTC
    Works for me too, even inside Tk:
    #!/usr/bin/perl -w use Tk; my $mw = MainWindow->new; my $key = $mw->Button( -text => 'Okay', -width => '10', -command => sub { my $cmd = q(perl -e 'warn "bad\nbad2\n"'); $pid = open(ERROR, "$cmd 2>&1 >/dev/null|"); while (<ERROR>) { print "ERROR: $_\n"; } } )->pack; MainLoop;
    Are you in Win32? STDERR redirection can definitely be flakey in win95 and win98 IIRC.

    --Bob Niederman, http://bob-n.com
Re: Sending STDERR to a filehandle
by sauoq (Abbot) on Jun 09, 2003 at 20:19 UTC

    I don't know. It works for me:

    $ perl -e 'open ERROR, "perl -le\"print q/stdout/; print STDERR q/stde +rr/\" 2>&1 1>/dev/null|"; while (<ERROR>) { print }' stderr

    Are you positive that the program is sending its errors to stderr?

    -sauoq
    "My two cents aren't worth a dime.";
    
Re: Sending STDERR to a filehandle
by ozone (Friar) on Jun 10, 2003 at 08:27 UTC
    change:
    $pid = open(ERROR, "$cmd 2>&1 1>/dev/null |");
    to
    $pid = open(ERROR, "$cmd 1>/dev/null 2>&1 |");
    I know that in Unix, putting them the wrong way around causes the same symptoms you are talking about.
      Actually, you're the one that has it backwards. Although most things hapopen letf-to-right, I've always found tht redirections happen right to left. Hence, you've arranged for STDOUT and STDERR both to go to /dev/null.

      --Bob Niederman, http://bob-n.com