Local::TeeOutput - Tee a file handle to two or more destinations
use Local::TeeOutput;
openTee(*FILEHANDLE, ">file1.ext", ">>file2.ext", "file3.ext", [etc...)]; print FILEHANDLE LIST printf FILEHANDLE "any string, scalar, list, or array"; closeTee(*FILEHANDLE);
$myfile = "file2.ext" openTee(*STDOUT, *STDOUT, ">>file1.ext", "$myfile", [etc...]); print LIST; closeTee(*STDOUT);
open(LOG, ">>file.ext"); openTee(*STDOUT, *STDOUT, *LOG);
Local::TeeOutput provides the means to send output information to multiple
destinations via a single filehandle. Local::TeeOutput exports
two functions, openTee()
and closeTee()
, both having a similar interface
to their standard perl functions counterparts open()
and close()
.
openTee()
uses the tie()
function to tie the specified filehandle to an
object. References to filehandles for the destinations are created
and stored within the object, and used by the object's methods to print to
the chosen destinations. The PRINT and PRINTF methods within the object
duplicate the operation of the standard perl functions print()
and
printf()
. closeTee()
closes the objects internal filehandles, frees
the original filehandle so that it can be use in a normal fashion, and
destroys the object that was created.
For the special case of the filehandle STDERR which does not require an
explicit print statement, openTee
will create a hook for the __WARN__ and
__DIE__ signal handlers that re-route the STDERR messages through an explicit
print statement. Conversely, closeTee
will reset the hooks back to default
if need be.
openTee(*FILEHANDLE,
<destination>[, <destination>, etc...]);
print FILEHANDLE
LIST;
printf FILEHANDLE
LIST;
closeTee(*FILEHANDLE)
;
The first parameter passed to the openTee()
function is the name of the
filehandle that you wish to tee. The first parameter can be any legal
filehandle name, either previously opened, or not. The filehandle must
be passed as an unquoted typeglob.
The remaining parameters are a list of destinations that you wish to tee
to. There is no limit to the number of destinations for the tee,
the minimum number is one. (For the degenerative case of one destination,
the programmer would be better served by the perl standard function open()
.)
A valid destination is either a previously opened filehandle, or a valid
filename. Filehandles as destinations must be passed as unquoted
typeglobs. A filename can be a string literal, or a scalar variable. In most
cases, filenames are passed inside of double quotes. If a filename is being
passed as a scalar variable, with no mode specified (see below), the
double quotes are optional. If the filename is a string literal, it can be
passed inside of single quotes.
Destinations that are filehandles are always opened in the append mode. Destinations that are filenames can be opened in overwrite (>) or append (>>) mode, by preceding the filename with the appropriate symbol(s). Append is the default mode for filenames, if no mode is specified.
Using the same filehandle for the first parameter and as one of the remaining parameters is acceptable provided that the filehandle has been previously opened (either by the programmer or by the system). This allows the programmer to send information both to the screen and to a report file at the same time. For example:
openTee(*STDOUT, *STDOUT, ">>log.txt");
The print()
and printf()
functions perform like, and use the same syntax
as, the standard perl functions print()
and printf()
. Please refer to
the documentation for those commands for details on their usage and syntax.
The closeTee()
function accepts a single parameter. The parameter must
be a filehandle that was opened by the openTee()
function. The filehandle
must be passed as an unquoted typeglob.
This module is pure perl code and therefore requires no special installation procedures. Based on the namespace conventions outlined in the documentation on the CPAN, until this module receives an official namespace, it is designed to be used from a ``<perl-path>\lib\Local'' directory. This is not a standard directory in the perl distribution and will most likely need to be created. After the directory has been created, copy the module to it, and it is ready to use.
If this module is (in the future) added to the CPAN, The namespace will be changed to whatever the powers-that-be deem. My most likely guess would be IO::TeeOutput.
If you wish to use a namespace other than Local::TeeOutput on your system, do a search and replace within the module for ``Local::'', and change it to your desired directory.
#!perl -w # # this example does not demonstrate all the possible permutations # of this module. It only shows a few of the basic (most useful) # possibilities. After this script is run, the screen should show # the following output: # # hello world # This is a test # one # two # 3 # another test # this will only print to the screen # this goes to the screen and the log file # # and the file logfile.txt should be created, and contain the # following output: # # hello world # This is a test # one # two # 3 # another test # this goes to the screen and the log file # this only prints to the log file
use Local::TeeOutput;
# tee STDOUT to a log file using a string literal openTee (*STDOUT, *STDOUT, ">logfile.txt");
# print a string literal to the tee print "hello world\n"; #STDOUT is the default file handle
# print a scalar to the tee $string = "This is a test"; print STDOUT "$string\n"; #use STDOUT explicitly
# print a list to the tee @list = (" one\n", " two\n", " 3\n"); print @list;
# print using printf to the tee $string1 = "another"; $string2 = "test"; printf "%10.10s%10.10s\n", $string1,$string2;
# close the tee closeTee(*STDOUT);
# print to the "non-tee'd" STDOUT print "this will only print to the screen\n";
# open a normal filehandle to the log file open (LOG, ">>logfile.txt");
# tee STDOUT to the log file via the filehandle openTee (*STDOUT, *STDOUT, *LOG);
# print to both STDOUT and LOG print "this goes to the screen and the log file\n";
# print to only the log file print LOG "this only prints to the log file\n";
__END__
This code has only been tested in some of the more basic of the many possible ways it could potentially be used. There are many untested scenarios that may produce bugs.
This module has been reported to work on all Win32 platforms, and Red Hat linux 5.0 (NL only termination). It should function on all other platforms as well, but they have not been verified.
When STDERR is tee-ed, the use of the eval
function as an exception
handler is disabled.
Compile time errors and warning cannot be tee-ed. Actually this is not really a bug. The module was not designed to do this sort of thing. For this capability, refer to Tie::STDERR
When STDERR is tee-ed, warnings and errors caused by printing to the tee will produce multiple messages, one for each tee'ed location
Implicit prints to STDOUT do not get tee'ed. For example the standard output
created by a call to the system()
function will only print to the screen.
As a work around to this, tee STDOUT and then print the return value from a
backticks operator (print `<command>`;)
perlfunc(1), perltie(1),
This man page documents ``Local::TeeOutput'' version 0.14.
0.14 | Dec. 20, 2000 | minor documentation changes 0.13 | July 22, 1998 | implemented stack trace subroutines allowing | stderr messages to point to the main code | rather than the module 0.12 | July 21, 1998 | added ability to tee both | STDERR and STDOUT to the same file 0.11 | July 13, 1998 | added support for STDERR 0.10 | June 6, 1998 | original release
Ron Wantock <ron.wantock@bench.com>ron.wantock@bench.com
Copyright (c) 2000 by Ron Wantock. All rights reserved.
This package is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
Milivoj Ivkovic for his ``bug hunting efforts''
Jan Pazdziora for the Tie::STDERR module from which I got the idea for solving the STDERR tee-ing problem, and Doug MacEachern for pointing me towards it.
The author of the Carp.pm module, for the stack trace subroutines