Copying Filehandles

Problem

You want to make a copy of a filehandle.

Solution

To create an alias for a filehandle, say:

*ALIAS = *ORIGINAL;

Use open with the & mode to create an independent copy of the file descriptor for the filehandle:

open(OUTCOPY, ">&STDOUT")   or die "Couldn't dup STDOUT: $!";
open(INCOPY,  "<&STDIN" )   or die "Couldn't dup STDIN : $!";

Use open with the &= mode to create an alias for that filehandle’s file descriptor:

open(OUTALIAS, ">&=STDOUT") or die "Couldn't alias STDOUT: $!";
open(INALIAS,  "<&=STDIN")  or die "Couldn't alias STDIN : $!";
open(BYNUMBER, ">&=5")      or die "Couldn't alias file descriptor 5: $!";

Discussion

If you create an alias for a filehandle with typeglobs, only one Perl I/O object is still being accessed. If you close one of these aliased filehandles, the I/O object is closed. Any subsequent attempt to use a copy of that filehandle will give you an error like "print on closed filehandle". When alternating access through the aliased filehandles, writes work as you’d expect because there’s no duplicated stdio data structure to get out of sync.

If you create a copy of a file descriptor with open(COPY, ">&HANDLE"), you’re really calling the dup (2) system call. You get two independent file descriptors whose file position, locks, and flags are shared, but which have independent stdio buffers. Closing one filehandle doesn’t affect its copy. Simultaneously accessing the file through both filehandles is a recipe for disaster. Instead, this technique is normally ...

Get Perl Cookbook now with O’Reilly online learning.

O’Reilly members experience live online training, plus books, videos, and digital content from 200+ publishers.