Local::TeeOutput - Tee a file handle to two or more destinations


    use Local::TeeOutput;
    openTee(*FILEHANDLE, ">file1.ext", ">>file2.ext", "file3.ext", [etc...)];
    printf FILEHANDLE "any string, scalar, list, or array";
    $myfile = "file2.ext"
    openTee(*STDOUT, *STDOUT, ">>file1.ext", "$myfile", [etc...]);
    print LIST;
    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...]);




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
    # 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";


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 <>


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 module, for the stack trace subroutines