[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