Reputation: 25133
Look at two examples:
$ perl -e ' print -e "registrar" && -d _ ? "YES" : "NO" '
YES
$ perl -e ' print -e "registrar" && -l _ ? "YES" : "NO" '
The stat preceding -l _ wasn't an lstat at -e line 1.
-d
and -l
are both file test operators. Why second does not work? The stat preceding -l _ is same as for -d _.
Upvotes: 0
Views: 114
Reputation: 52354
Most of the file tests use stat
, which follows symlinks; -l
uses lstat
because it makes no sense to follow one if you want to test if it itself is a symbolic link. Hence the error.
The diagnostics
pragma can be used to give a more verbose explanation of errors and warnings, including this one:
$ perl -Mdiagnostics -E 'say -e "registrar" && -l _ ? "YES" : "NO" '
The stat preceding -l _ wasn't an lstat at -e line 1 (#1)
(F) It makes no sense to test the current stat buffer for symbolic
linkhood if the last stat that wrote to the stat buffer already went
past the symlink to get to the real file. Use an actual filename
instead.
Uncaught exception from user code:
The stat preceding -l _ wasn't an lstat at -e line 1.
If using perl 5.10 or newer, file tests can be directly chained without needing to be &&
ed together. Doing this with -e
and -l
works since perl is smart enough to pick the appropriate stat function:
$ mkdir registrar
$ perl -E ' say -e -d "registrar" ? "YES" : "NO" '
YES
$ perl -E ' say -e -l "registrar" ? "YES" : "NO" '
NO
I actually need exists and not link. Is there short hand for that?
That shorthand notation only works for simple and-ing all the tests together, but you can call lstat
directly to see if a file exists:
$ ln -s registrar registrar-link
$ perl -E 'say lstat "registrar" && ! -l _ ? "YES" : "NO" '
YES
$ perl -E 'say lstat "registrar-link" && ! -l _ ? "YES" : "NO" '
NO
$ perl -E 'say lstat "no-such-file" && ! -l _ ? "YES" : "NO" '
NO
And in a script as opposed to a one-liner, I'd use File::stat
instead of the underscore notation.
Upvotes: 5