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 _.
CodePudding user response:
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.
Also, as of perl 5.10, 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?
The shorthand notation only works for 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.