I ran into the following and still do not understand entirely the rationale behind this. If someone could explain why things are as they are I'd be thankful.
The following was tested on AIX 7.1 with ksh88, but i suspect that to be ubiquitous. In an installation routine i had to create a set of symbolic links. Because they might already exist i used test -e filename to test it:
if [ ! -e /some/link ] ; then
ln -s /path/to/file /some/link
fi
This didn't work as expected because test returned 0 only if the link AND its target existed. If only the link exists but not the file referenced by it test will return 1.
-e pathname
True if pathname resolves to a file that exists. False if pathname cannot be resolved.
A "file that exists" is IMHO covered by a link, even if this link points to a file which doesn't. I can stat() this file and do many other operations on it which can be done with a file.
I do understand that i can use "-L", which tests for a link but i would like to understand the rationale behind the behavior. Or is the POSIX documentation inconsistent here?
$ ls -l a b
ls: cannot access a: No such file or directory
lrwxrwxrwx 1 RBATTE1 TS 1 Mar 11 13:32 b -> a
$ if [ -L b ]
> then
> echo hit
> else
> echo miss
> fi
hit
See my first post above, i know that. The question is: why does "-e" work like it does and: is the POSIX documentation buggy there? According to the definition of "file" it should work like this:
if "file" exists and:
is a regular file, "-f" will return TRUE
is a block special file "-b" will return TRUE
is a directory "-d" will return TRUE
...etc. analogously for "-c", "-h", "L", "-p", ...
and "-e" should return TRUE if any one of the above return TRUE.
I suppose it all depends on your definition of what is a file in "resolves to a file". Does it mean a file being with content and just a plain regular file, or does it mean any entity within a directory. How about a directory even? That does seem to be considered as a file.
It should be that everything is a file, but the word resolves perhaps covers the symbolic link issue that's being illustrated.
All very wordy stuff. I bet a lawyer would love it.
Robin is correct. It all depends on what resolves means. And, the standards lawyers love stuff like this. And, the text agenda.kgb quoted:
is the key here. If the function you're using is stat (), then pathname resolution is NOT complete when the final component of a path names a symbolic link and the file named by the symlink does not exist. If the function you're using is lstat (), then pathname resolution is complete because the description of the stat () and lstat () functions explicitly states:
And, in the Commands and Utilities Volume of the POSIX standards, pathname resolution is not complete when a symlink is found at the end of the path unless the utility description explicitly states that a symbolic link is being processed rather than the file the symlink references. The description of test -L pathname is:
which makes it clear that for the -L option, test needs to use the equivalent of lstat(pathname, ...) . But, the description of test -e :
does not make any exception for symlinks. So, it needs to use the equivalent of stat(pathname, ...) .
Speaking as a standards lawyer, it appears to me that the ksh88 AIX 7.1 test -e and test -L utility is behaving properly.
I did some tracings.
Indeed test -L does an lstat() i.e. does not try to follow a symlink. test -e does either a stat() or an access() i.e. follows a symlink and a symlink's symlink... This is meant with "resolve".
In order to test for anything, you need test -L "$file" || test -e "$file" .