Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I check if a filehandle is open in Perl? [duplicate]

Please see the answer regarding openhandle() from Scalar::Util. The answer I originally wrote here was once the best we could do, but it's now badly outdated.


The Scalar::Util module provides the openhandle() function for this. Unlike fileno(), it handles perl filehandles which aren't associated with OS filehandles. Unlike tell(), it doesn't produce warnings when used on an unopened filehandle From the module's documentation:

openhandle FH

Returns FH if FH may be used as a filehandle and is open, or FH is a tied handle. Otherwise "undef" is returned.

   $fh = openhandle(*STDIN);           # \*STDIN
   $fh = openhandle(\*STDIN);          # \*STDIN
   $fh = openhandle(*NOTOPEN);         # undef
   $fh = openhandle("scalar");         # undef

Why would you want to do that? The only reason I can think of is when you're using old style package filehandles (which you seem to be doing) and want to prevent accidentally saving one handle over another.

That issue can be resolved by using new style indirect filehandles.

open my $fh, '<', $filename or die "Couldn't open $filename: $!";

Perl provides the fileno function for exactly this purpose.

EDIT I stand corrected on the purpose of fileno(). I do prefer the shorter test

fileno FILEHANDLE

over

tell FH != -1


Tell produces a warning (so does stat, -s, -e, etc..) with use warnings (-w)

perl -wle '
    open my $fh, "<", "notexists.txt"; 
    print "can stat fh" if tell $fh
'
tell() on closed filehandle $fh at -e line 1.
-1

The alternatives fileno($fh) and eof($fh) do not produce warnings. I found the best alternative was to save the output from open.