[ACCEPTED]-How do I resolve a "print() on closed filehandle" error in Perl?-file-io

Accepted answer
Score: 33

You want to do some action on MYFILE after you 14 (or the interpreter itself because of an 13 error) closed it.

According to your code 12 sample, the problem could be that open doesn't 11 really open the file, the script may have 10 no permission to write to the file.

Change 9 your code to the following to see if there 8 was an error:

open(MYFILE, ">", "/home/abc/xrt/sdf/news/top.html") or die "Couldn't open: $!";


ysth pointed out that -w is not really 7 good at checking if you can write to the 6 file, it only ‘checks that one of the relevant 5 flags in the mode is set’. Furthermore, brian d foy told 4 me that the conditional I've used isn't 3 good at handling the error. So I removed 2 the misleading code. Use the code above 1 instead.

Score: 14

It appears that the open call is failing. You 7 should always check the status when opening a 6 filehandle.

my $file = '/home/abc/xrt/sdf/news/top.html';
open(MYFILE, ">$file") or die "Can't write to file '$file' [$!]\n";
close MYFILE;

If the open is unsuccessful, the 5 built-in variable $! (a.k.a. $OS_ERROR) will 4 contain the OS-depededant error message, e.g. "Permission 3 denied"

It's also preferable (for non-archaic 2 versions of Perl) to use the three-argument 1 form of open and lexical filehandles:

my $file = '/home/abc/xrt/sdf/news/top.html';
open(my $fh, '>', $file) or die "Can't write to file '$file' [$!]\n";
print {$fh} $DATA;
close $fh;
Score: 6

An alternate solution to saying or die is to use 3 the autodie pragma:


use strict;
use warnings;
use autodie;

open my $fh, "<", "nsdfkjwefnbwef";

print "should never get here (unless you named files weirdly)\n";

The code above produces the 2 following error (unless a file named nsdfkjwefnbwef 1 exists in the current directory):

Can't open 'nsdfkjwefnbwef' for reading: 'No such file or directory' at example.pl line 7
Score: 3



In modern Perl, it could be written as:

open(my $file_fh, ">", "/home/abc/xrt/sdf/news/top.html") or die($!);

This way 8 you get a $variable restricted to the scope, there 7 is no "funky business" if you 6 have weird filenames (e.g. starting with 5 ">") and error handling (you 4 can replace die with warn or with error 3 handling code).

Once you close $file_fh or 2 simply go out of scope, you can not longer 1 print to it.

Score: 3

I had this problem when my files were set 2 to READ-ONLY.

Check this also, before giving 1 up! :)

Score: 2

Check that the open worked

if(open(my $FH, ">", "filename") || die("error: $!"))
    print $FH "stuff";


Score: 2

If you use a global symbol MYFILE as your 12 filehandle, rather than a local lexical 11 ($myfile), you will invariably run into 10 issues if your program is multithreaded, e.g. if 9 it is running via mod_perl. One process 8 could be closing the filehandle while another 7 process is attempting to write to it. Using 6 $myfile will avoid this issue as each instance 5 will have its own local copy, but you will 4 still run into issues where one process 3 could overwrite the data that another is 2 writing. Use flock() to lock the file while 1 writing to it.

Score: 1

Somewhere in you're script you will be doing 8 something like:

open MYFILE, "> myfile.txt";
# do stuff with myfile
close MYFILE;
print MYFILE "Some more stuff I want to write to myfile";

The last line will throw 7 an error because MYFILE has been closed.


After 6 seeing your code, it looks like the file 5 you are trying to write to can't be opened 4 in the first place. As others have already 3 mentioned try doing something like:

open MYFILE, "> myfile.txt" or die "Can't open myfile.txt: $!\n"

Which 2 should give you some feedback on why you 1 can't open the file.

More Related questions