in reply to Capturing STDERR (this is not a FAQ)

The child process cannot access variables or call subroutines in your process. So your second criteria cannot be met. You will need to have the child write to a pipe from which you will read and write to the tied handle.

use IPC::Open3 qw( open3 ); open(local *CHILD_STDIN, '<', '/dev/null') or die $!; my $pid = open3( '<&CHILD_STDIN', '>&STDOUT', local *CHILD_STDERR, 'ls file-that-does-not-exist.txt', ); while (<CHILD_STDERR>) { print $tied_fh $_; } waitpid($pid, 0);
IPC::Open3 is quite low level. IPC::Run3 and/or IPC::Run can surely make this much simpler.

Replies are listed 'Best First'.
Re^2: Capturing STDERR (this is not a FAQ)
by mikosullivan (Novice) on Feb 10, 2015 at 06:52 UTC
    OK, except here's where I'm unclear. This command sorta does what I want:
    open (STDERR, '>', './log.txt')
       or die "could not open STDERR: $!\n";
    
    It captures STDERR from child processes without any calls to system or backticks or whatever having to be called in a special way. The problem is that it only redirects to a file. Isn't there some way to redirect it to a subroutine or file handle instead?
      It captures STDERR from child processes without any calls to system or backticks or whatever having to be called in a special way.

      That's because child processes inherit their stdin/stdout/stderr from their parent processes.

      But file handles are OS level entities, not language specific entities. A tied filehandle is a perl-level entity; it cannot be inherited by a C program.


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority". I'm with torvalds on this
      In the absence of evidence, opinion is indistinguishable from prejudice. Agile (and TDD) debunked

      This sounds promising.

      From perl's core documentation: open
      Here is a script that saves, redirects, and restores STDOUT and STDERR + using various methods: #!/usr/bin/perl open(my $oldout, ">&STDOUT") or die "Can't dup STDOUT: $!"; open(OLDERR, ">&", \*STDERR) or die "Can't dup STDERR: $!"; open(STDOUT, '>', "foo.out") or die "Can't redirect STDOUT: $!"; open(STDERR, ">&STDOUT") or die "Can't dup STDOUT: $!"; select STDERR; $| = 1; # make unbuffered select STDOUT; $| = 1; # make unbuffered print STDOUT "stdout 1\n"; # this works for print STDERR "stderr 1\n"; # subprocesses too open(STDOUT, ">&", $oldout) or die "Can't dup \$oldout: $!"; open(STDERR, ">&OLDERR") or die "Can't dup OLDERR: $!"; print STDOUT "stdout 2\n"; print STDERR "stderr 2\n";
      Bill
        The OP is already doing that, and it won't work for tied handles for the reasons already stated, so it doesn't help the OP.

      Isn't there some way to redirect it to a subroutine

      The child process cannot access variables or call subroutines in your process. You will need to have the child write to a pipe from which you will read, then you can pass what you read to a subroutine.

      or file handle instead?

      huh? "Redirecting data sent to a file handle to a file handle" makes no sense.

      A reply falls below the community's threshold of quality. You may see it by logging in.