The POSIX shell standard says on this site
http://pubs.opengroup.org/onlinepubs/9699919799/
about how shells use PATH
to look for executables:
"The list shall be searched from beginning to end, applying the filename to each prefix, until an executable file with the specified name and appropriate execution permissions is found."
Well, this is not how this appears to work in real POSIX implementation:
man which
says:
"returns the pathnames of the files (or links) which would be executed in the current environment, had its arguments been given as commands in a strictly POSIX-conformant shell. It does this by searching the PATH for executable files matching the names of the arguments. It does not follow symbolic links."
OK, let's look at this situation:
$ pwd
/home/mark
$ echo $PATH
…
/home/mark/bin:
$ ls -l bin/foobar
lrwxrwxrwx 1 mark mark 18 Dec 12 22:51 bin/foobar -> /home/mark/foobar1
$ touch foobar1
$ which foobar
$ chmod a+x foobar1
$ which foobar
/home/mark/bin/foobar
OK, here is a symbolic link in PATH
with the correct name, and it is reported by ls
to be executable.
which
does not look at it at all,
but is only interested in what it points to.
That despite the fact that both man which
explicitly says that it does not follow symbolic links (and indeed we see it doesn't, because which foobar
does not print foobar1
), and also that the POSIX shell documentation quoted above, never ever mentions following symlinks in the PATH
algorithm.
So, is which
and the existing shells wrong, or am I not understanding the documentation?
TO CLARIFY:
I know and can explain the existing behaviour. My question is not "how does this work?". That I know.
My question is about documentation: where is my mistake in following the documentation that I quoted. Or is the documentation wrong?
MOTIVATION:
Why do I care?
Well, I am an implementer. Different implementers have different requirements. For me, the requirement is that the word of the current POSIX standard MUST be followed EXACTLY (or, more precisely, the best it can be, because, the standard itself is somewhat buggy). Like as it were the word of God.
Now, the standard wording is pretty clear – following symlinks is not mentioned, where in many other places, it is mentioned where it needs to be done. So in this case, don't.
However, I always double check how dash
and bash
behave, just to make sure. Now of course, there is a little problem here as well, dash
even though it is billed as POSIX, has plenty of small bugs with conformance to POSIX. bash
, I have yet to find any bugs with POSIX, but… bash isn't actually POSIX, it is much more than that.
So there you have it. That is why I care.
Best Answer
The permissions of the symlink itself are irrelevant. You couldn't even change them if you tried.
What matters are permissions of the underlying file.
It is fine to have directories in your PATH include symlinks to executables. In fact, it is likely that many executables in your PATH are symlinks. For example, on debian/ubuntu-like systems:
Documentation
From
man chmod
:Example
The shell has a test,
-x
, to determine if a file is executable. Let's try that:So, just like you found with
which
, the shell does not consider a softlink executable unless the underlying file is executable.How which works
On a Debian system,
which
is a shell script. The relevant section of the code is:As you can see, it uses the
-x
test to determine is a file is executable.POSIX specifies the
-x
test as follows:So, POSIX checks what the pathname resolves to. In other words, it accepts symlinks.
POSIX exec function
The POSIX exec function follows symlinks. The POSIX spec goes on at length to specify error conditions it may report if symlinks are circular or too deep, such as: