Filehandles, files, directories
open#
Associate a filehandle with a file, a command, or an in-memory scalar.
open is the primary way a Perl program acquires a filehandle. The
three-argument form — open $fh, MODE, EXPR — is the one to use in
new code: the mode is stated explicitly, the filename cannot be
reinterpreted as a shell pipeline, and leading or trailing whitespace
in EXPR is preserved verbatim. The older two-argument form exists
for compatibility and for the “magic” filename interpretation it
enables; do not feed it untrusted input.
Synopsis#
open my $fh, "<", $path or die "read $path: $!";
open my $fh, ">", $path or die "write $path: $!";
open my $fh, ">>", $path or die "append $path: $!";
open my $fh, "+<", $path or die "rw $path: $!";
open my $fh, "<:encoding(UTF-8)", $path or die $!;
open my $mem, ">", \$buf or die $!; # in-memory
open my $pipe, "-|", "ls", "-la" or die $!; # read from cmd
open my $pipe, "|-", "gzip", ">$f" or die $!; # write to cmd
What you get back#
1 on success; undef on failure, with $! set to the OS error.
For the pipe forms (|- / -|), the successful return value is the
pid of the child process — useful when you need to waitpid on it
later. After a one- or two-argument pipe open on the literal command
-, open returns twice (parent gets the child pid, child gets 0);
use defined($pid) or // to distinguish the two.
Always check the return value. A failed open leaves the filehandle
closed, and every subsequent read or write on it will set $! to
Bad file descriptor and emit a warning under use warnings.
open my $fh, "<", $path
or die "open $path: $!";
Global state it touches#
$!— set on failure to the OS-level error.${^OPEN}— default I/O layers installed by theopenpragma or the-CioDswitch. These apply only whenMODEin the three-argument form contains no explicit layer; a bare<or>honours them,<:rawor any other explicit layer suppresses them.$^F— highest file descriptor not marked close-on-exec; the new fd inherits the close-on-exec flag based on this.Selected filehandle via
select— unchanged byopen, but becomes relevant the moment youprintto the new handle without naming it.For pipe forms,
$?and${^CHILD_ERROR_NATIVE}are set when the handle is later closed.
Modes#
The second argument names an I/O role. The common cases:
Mode |
Meaning |
|
|---|---|---|
|
read |
|
|
write, truncate or create |
|
|
append, create if missing |
|
|
read and write, no truncation |
|
|
read and write, truncate first |
|
|
pipe to command (we write) |
— |
|
pipe from command (we read) |
— |
|
dup or fdopen an existing handle |
— |
Newly created files get permissions 0666 & ~umask. +< is almost
always what you want for read-write; +> clobbers the file first.
I/O layers attach after the mode: <:encoding(UTF-8), >:raw,
>>:crlf, <:encoding(UTF-8):crlf. An explicit layer suppresses
${^OPEN} defaults; a lone colon (<:) falls back to the OS default
(:raw on Unix, :crlf on Windows).
Examples#
Read a UTF-8 text file line by line:
open my $fh, "<:encoding(UTF-8)", "notes.txt"
or die "open notes.txt: $!";
while (my $line = <$fh>) {
chomp $line;
# ... use $line ...
}
close $fh or warn "close: $!";
Write a binary file with no encoding translation:
open my $out, ">:raw", "image.bin"
or die "open image.bin: $!";
print $out $bytes;
close $out or die "close: $!";
In-memory filehandle — print into a scalar, useful for capturing
output that expects a real handle:
my $buf = "";
open my $mem, ">", \$buf or die $!;
print $mem "hello\n";
close $mem;
# $buf now contains "hello\n"
Read from a command, list form so arguments are not subject to shell metacharacter interpretation:
open my $ls, "-|", "ls", "-la", $dir
or die "ls: $!";
while (<$ls>) { print }
close $ls; # $? holds the exit status
Temporary anonymous file — pass undef as the third argument with a
read-write mode, then seek back to the start to read what you wrote:
open my $tmp, "+>", undef or die $!;
print $tmp "scratch data\n";
seek $tmp, 0, 0;
my $line = <$tmp>;
Edge cases#
Two-argument “magic” open:
open $fh, $namehonours leading<,>,>>, a trailing|, and strips surrounding whitespace from$name. Fine for a literal filename you typed yourself; never for a filename that came from user input, the network, or an environment variable. Use the three-argument form.Two-argument
-:open $fh, "<-"oropen $fh, "-"opensSTDIN;open $fh, ">-"opensSTDOUT. Three-argument equivalents areopen $fh, "<", "-"andopen $fh, ">", "-".Reopening
STDOUT/STDERR: close them first, then reopen against the new target.open STDOUT, ">", \$bufredirects all subsequentprint STDOUToutput into$buf.Bareword filehandles (
open FH, ...) are package globals and are disabled underuse v5.36or later via thebareword_filehandlesfeature. Prefer a lexical scalar.Layers and
${^OPEN}: any explicit layer, even:, disables the defaults from theopenpragma. If you rely on a pragma default, omit the colon entirely (<, not<:).Pipe to a command with shell metacharacters: the two-argument pipe form (
open $fh, "|cat -n | lpr") runs through/bin/sh -c. The three-argument list form (open $fh, "|-", "cat", "-n") does not and is the safer default.In-memory scalar strings: treated as octet strings. Without truncation, the scalar may not contain code points above
0xFF.Automatic close on scope exit: a lexical filehandle closes when its refcount hits zero, but the implicit close does not report errors. For files you wrote to, close explicitly and check the return value.
openvssysopen:openwrapsfopen(3)semantics with PerlIO layers on top. For directopen(2)flags likeO_EXCLorO_NOFOLLOW, usesysopen.
Differences from upstream#
Fully compatible with upstream Perl 5.42.
See also#
close— release a filehandle; check its return value for buffered writes and pipe commandssysopen— open with rawopen(2)flags when you needO_EXCL,O_NOFOLLOW, or similar precisionbinmode— push or replace I/O layers on an already open handleread— fixed-size byte reads from the handleopenreturnedreadline— record-at-a-time reads (what<$fh>calls)fileno— the underlying OS file descriptor, forflock,select, orfcntl