[Wellington-pm] perl -f check failed

Jacinta Richardson jarich at perltraining.com.au
Wed Jul 21 01:07:47 PDT 2010


Jethro Carr wrote:

> Essentially the script creates a number of text files whilst running and
> checks if any exist using -f - if they do, it knows to use a different
> name for the new file.
> 
> This has been working nicely for hundreds of files a week for almost a
> year, however the other day we experienced an issue where -f returned
> false despite a file existing, which lead to some interesting
> overwrites...

Technically, -f does not test whether a file exists, it tests whether a given 
file is a "plain file" as opposed to a directory, a device etc.

To test for existence you need -e

Thus:

* An empty file will return true for -e, and true for -f

% touch foo
% perl -e 'print "exists\n" if -e "foo"; print "plain\n" if -f "foo"';
exists
plain


* Directories will return true for -e and false for -f

% perl -e 'print "exists\n" if -e "/tmp"; print "plain\n" if -f "/tmp"';
exists

* Symlinks will return true for -e and true for -f (which surprised me)

% ln -s foo bar
% perl -e 'print "exists\n" if -e "bar"; print "plain\n" if -f "bar"';
exists
plain

* Devices will return true for -e and false for -f

%perl -e 'print "exists\n" if -e "/dev/tty0"; print "plain\n" if -f "/dev/tty0"';
exists

There are probably other situations where -e and -f disagree, and I suspect you 
struck one, although I can't say for sure.  The point I'm making is that your 
test is wrong.  If you want to test that a file both exists and is a plain file, 
then you need to use both tests:

	if(-e $file && -f _)

All the best,

	Jacinta


More information about the Wellington-pm mailing list