NAME Local::TeeOutput - Tee a file handle to two or more destinations SYNOPSIS 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); DESCRIPTION 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()". Internals "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. Syntax: "openTee(*FILEHANDLE," [, , 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. INSTALLATION 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 "\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. EXAMPLE #!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__ CAVEATS 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. BUGS 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 ``;) SEE ALSO perlfunc(1), perltie(1), VERSION This man page documents "Local::TeeOutput" version 0.14. HISTORY 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 AUTHOR Ron Wantock ron.wantock@bench.com COPYRIGHT Copyright (c) 2000 by Ron Wantock. All rights reserved. LICENSE This package is free software; you can redistribute it and/or modify it under the same terms as Perl itself. THANKS TO 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