Printing to Many Filehandles Simultaneously (Perl Cookbook, 2nd Edition)

## 7.8. Printing to Many Filehandles Simultaneously

### 7.8.1. Problem

You need to output the same data to several different filehandles.

### 7.8.2. Solution

If you want to do it without forking, write a `foreach` loop that iterates across the filehandles:

>     foreach $filehandle (@FILEHANDLES) {
>         print $filehandle $stuff_to_print;
>     }

If you don't mind forking, open a filehandle that's a pipe to a tee program:

>     open(MANY, "| tee file1 file2 file3 > /dev/null")   or die $!;
>     print MANY "data\n"                                 or die $!;
>     close(MANY)                                         or die $!;

If you don't have a tee program handy, use the IO::Tee module from CPAN:

>     use IO::Tee;
>     $tee = IO::Tee->new(@FILEHANDLES);
>     print $tee $stuff_to_print;

### 7.8.3. Discussion

A filehandle sends output to one file or program only. To duplicate output to several places, you must call `print` multiple times or make a filehandle connected to a program like tee, which distributes its input elsewhere. If you use the first option, it's probably easiest to put the filehandles in a list or array and loop through them (see Recipe 7.5):

>     for $fh (*FH1, *FH2, *FH3)      { print $fh "whatever\n" }

However, if your system supports the tee(1) program, or if you've installed the Perl version from Recipe 8.25, you may open a pipe to tee and let it do the work of copying the file to several places. Remember that tee normally also copies its output to `STDOUT`, so you must redirect tee's standard output to /dev/null if you don't want an extra copy:

>     open (FH, "| tee file1 file2 file3 >/dev/null");
>     print FH "whatever\n";

You could even redirect your own `STDOUT` to the tee process, and then you're able to use a regular `print` directly:

>     # make STDOUT go to three files, plus original STDOUT
>     open (STDOUT, "| tee file1 file2 file3") or die "Teeing off: $!\n";
>     print "whatever\n"                       or die "Writing: $!\n";
>     close(STDOUT)                            or die "Closing: $!\n";

The IO::Tee module from CPAN gives you a single filehandle (an object of the IO::Tee class) that you can write to. The object prints to many different filehandles whatever you print to it. Pass destination filehandles to the constructor:

>     use IO::Tee;

>     $t = IO::Tee->new(*FH1, *FH2, *FH3);
>     print $t "Hello, world\n";
>     print $t "Goodbye, universe\n";

In addition to `print`, you can do any I/O operation you like to an IO::Tee filehandle. For example, if you `close` `$t` in the preceding example, the `close` will return true if `FH1`, `FH2`, and `FH3` were all successfully closed.

### 7.8.4. See Also

The `print` function in perlfunc(1) and in Chapter 29 of Programming Perl; the "Typeglobs and Filehandles" sections of Chapter 2 of Programming Perl; the documentation for the CPAN module IO::Tee; we use this technique in Recipe 8.25 and Recipe 13.15

Copyright © 2003 O'Reilly & Associates. All rights reserved.