Re: Redirecting STDOUT and standard error to file
by Zaxo (Archbishop) on Sep 08, 2005 at 20:50 UTC
|
IO::Tee will do what you want. It's a little tricky to "cast" (C-speak) an IO::Tee object to a global handle, but this will do it. Perl 5.8x with PerlIO.
my $exitcode = do {
use IO::Tee;
open my $ef, '>>', '/path/to/stderr.txt' or die $!;
open my $of, '>>', '/path/to/stdout.txt' or die $!;
local *STDERR = *{IO::Tee->new('> /dev/tty', $ef)};
local *STDOUT = *{IO::Tee->new('> /dev/tty', $of)};
warn scalar localtime;
print scalar(localtime), "\n";
warn 'Here I am!';
print "Here, too!\n";
system '/loc/of/perl', '/path/to/sample1.pl';
};
As with any localized global variable, subroutines called from the local scope will honor the local value.
| [reply] [d/l] |
Re: Redirecting STDOUT and standard error to file
by jfroebe (Parson) on Sep 08, 2005 at 20:24 UTC
|
Hi
To do so, you would either have to write to STDOUT and to a text file in your sample1.pl OR write a variation of the tee program. Something like:
sub print_out {
my $text = shift;
my $FH = shift;
print $text;
print $FH $text;
}
print_out "hi there\n";
Jason L. Froebe
Team Sybase member No one has seen what you have seen, and until that happens, we're all going to think that you're nuts. - Jack O'Neil, Stargate SG-1
| [reply] [d/l] |
Re: Redirecting STDOUT and standard error to file
by eff_i_g (Curate) on Sep 08, 2005 at 20:47 UTC
|
#!/usr/bin/perl -w
use strict;
sub multiprint {
for (*FILE, *STDOUT) {
print $_ @_;
}
}
open FILE, '>tmp' or die;
multiprint('test');
close FILE;
not sure how to handle the STDERR yet... | [reply] [d/l] |
Re: Redirecting STDOUT and standard error to file
by davidrw (Prior) on Sep 08, 2005 at 21:01 UTC
|
googling for "tee exit code" i found this that works (source):
(/bin/foo ; echo $? >RES)| tee -a $LOGFILE
export ERR=$(cat RES)
I also found this posting (see also man bash and search for PIPESTATUS) that says that this will work:
$ cat test
#!/bin/bash
echo foo
sleep 2
echo bar
false
$ ./test | tee blah
foo
[.. seconds later..]
bar
$ echo ${PIPESTATUS[@]}
1 0
# (so ${PIPESTATUS[0]} should give you the return of the first comma
+nd).
But i was unable to get it to work (PIPESTATUS seemed to always have just one element of 0)... | [reply] [d/l] [select] |
|
$ uname -s -r
FreeBSD 5.4-RELEASE
$ bash --version
GNU bash, version 2.05b.0(1)-release (i386-portbld-freebsd4.8)
Copyright (C) 2002 Free Software Foundation, Inc.
man bash extract:
- PIPESTATUS
-
An array variable (see Arrays below) containing a list of exit
status values from the processes in the most-recently-executed
foreground pipeline (which may contain only a single command).
| [reply] [d/l] [select] |
Re: Redirecting STDOUT and standard error to file
by sh1tn (Priest) on Sep 08, 2005 at 20:52 UTC
|
| [reply] |
Re: Redirecting STDOUT and standard error to file
by eyepopslikeamosquito (Archbishop) on Sep 08, 2005 at 22:16 UTC
|
Back in 1996,
Tom Christiansen's celebrated "Csh Programming Considered Harmful" post
showed how it can be done
even in humble /bin/sh (but not in csh, of course ;-) as follows:
Consider the pipeline:
A | B | C
You want to know the status of C, well, that's easy: it's in $?, or
$status in csh. But if you want it from A, you're out of luck -- if
you're in the csh, that is. In the Bourne shell, you can get it, although
doing so is a bit tricky. Here's something I had to do where I ran dd's
stderr into a grep -v pipe to get rid of the records in/out noise, but had
to return the dd's exit status, not the grep's:
device=/dev/rmt8
dd_noise='^[0-9]+\+[0-9]+ records (in|out)$'
exec 3>&1
status=`((dd if=$device ibs=64k 2>&1 1>&3 3>&- 4>&-; echo $? >&4)
+|
egrep -v "$dd_noise" 1>&2 3>&- 4>&-) 4>&1`
exit $status;
Update: Please note that the above block quoted text is a direct quote from Tom Christiansen's post.
| [reply] [d/l] [select] |
|
Given that the original poster asked about using "tee.exe", I assume he's running a Windows variant. Neither csh nor the bourne shell nor even dd is installed on Windows by default; and so it's not a great idea to assume that his default shell isn't just "command.com" in his case.
Your points are all correct; just probably a bit too UNIX centric for the original poster to make use of. It's nice to want to help, but let's try to pick up on the subtle cues (operating system in use, etc.) that will make our advice that much more useful to the people who ask for it.
The wiser we all try to be, the more powerful the monestary will become, until one day we TAKE OVER THE WORLD!!! :-)
| [reply] |
|
You are correct. I am running a windows XP/2000 machine and most of the solutions are Unix centric and I am not able to use them.
| [reply] |
|
Great post. I have one question you may wish to ponder - what the heck is going on with fd 3 in this example? As far as I can see, the manipulations of fd 3 are (as with dd's output in the example) just noise. I know its OT, but I wonder about this.
| [reply] |
Re: Redirecting STDOUT and standard error to file
by jhourcle (Prior) on Sep 09, 2005 at 12:11 UTC
|
script file.log
perl -w sample1.pl 2>&1
echo $?
exit
col -b file.log > stdout.txt
Note -- script will save _everything_ that goes be the terminal into a file, which is why you need to pass it through col to get a more sane log file. It may be an advantage or disadvantage that everything gets saved, including subsequent commands, until you exit script. | [reply] [d/l] |
Re: Redirecting STDOUT and standard error to file
by /dev/luser (Acolyte) on Sep 09, 2005 at 10:19 UTC
|
The Perl Cookbook has a nice recipe to copy filehandles. For example:
open (COPYOUT, ">&STDOUT");
open (COPYERR, ">&STERR");
This book is *highly* recommended :-) HTH | [reply] [d/l] |