I have searched the internet for different solutions and the closest I have done is an exercise in open
statements:
use strict;
use warnings;
use Carp;
# Save previous state
my ($old_out, $old_err);
open($old_out, ">&", \*STDOUT) or
croak("Cannot save STDOUT: $!\n");
open($old_err, ">&", \*STDERR) or
croak("Cannot save STDERR: $!\n");
my ($fh_OUTLOG);
# Make a filehandle for the tee output
open($fh_OUTLOG, "|-", "tee out_err.log") or
croak("Cannot open filehandle to tee to log file: $!\n");
# Duplicate STDOUT and STDERR to the filehandle
open(STDOUT, ">&", $fh_OUTLOG) or
croak("Cannot duplicate STDOUT to filehandle: $!\n");
open(STDERR, ">&", $fh_OUTLOG) or
croak("Cannot duplicate STDERR to filehandle: $!\n");
# Code...
# Restore STDOUT
open(STDOUT, ">&", $old_out) or
croak("Cannot restore STDOUT: $!\n");
# Close the filehandle
close $fh_OUTLOG
or croak( ($!) ? "Error closing fh_OUTLOG: $!"
: "Exit status $? from tee log.out");
# Restore STDERR
open(STDERR, ">&", $old_err) or
croak("Cannot restore STDERR: $!\n");
But this code will not produce an log file with STDERR, and I dont know how to add it. The criteria for the solution are:
- Perl v 5.8.3.
- No CPAN modules.
- No Bash extra command to start the script.
I was thinking of using some tee
solutions for STDERR as well:
open(STDERR, "| tee log.err");
open(STDERR, ">&", $fh_OUTLOG);
But using this will hang the script in the end of the execution. (Think the tee child process still is alive). But the script still hangs if I try to kill it in the end.
my $pid_std_err = open(STDERR, "| tee log.err") or
croak("Cannot tee filehandle STDERR to log.err: $!\n");
# Code...
kill -9, $pid_std_err;