Eugen Konkov
Eugen Konkov

Reputation: 25133

The stat preceding -l _ wasn't an lstat

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

Answers (1)

Shawn
Shawn

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

Related Questions