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

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?
  • Comment on Re^2: Capturing STDERR (this is not a FAQ)

Replies are listed 'Best First'.
Re^3: Capturing STDERR (this is not a FAQ)
by BrowserUk (Patriarch) on Feb 10, 2015 at 07:16 UTC
    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
Re^3: Capturing STDERR (this is not a FAQ)
by BillKSmith (Monsignor) on Feb 10, 2015 at 13:59 UTC

    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.
Re^3: Capturing STDERR (this is not a FAQ)
by ikegami (Patriarch) on Feb 10, 2015 at 14:57 UTC

    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.