Стандарт оболочки POSIX говорит на этом сайте
http://pubs.opengroup.org/onlinepubs/9699919799/
о том, как оболочки используют PATHдля поиска исполняемых файлов:
«Список следует искать от начала до конца, применяя имя файла к каждому префиксу, пока не будет найден исполняемый файл с указанным именем и соответствующими разрешениями на выполнение».
Ну, это не то, как это работает в реальной реализации POSIX:
man which говорит:
"возвращает пути к файлам (или ссылкам), которые были бы выполнены в текущей среде, если бы его аргументы были заданы как команды в строго POSIX-совместимой оболочке. Это делается путем поиска в PATH исполняемых файлов, соответствующих именам аргументы. Он не следует за символическими ссылками. "
Хорошо, давайте посмотрим на эту ситуацию:
$ 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
Хорошо, вот символическая ссылка PATHс правильным именем, и она сообщается lsкак исполняемая.
which не смотрит на это вообще, а интересуется только тем, на что он указывает.
Это несмотря на тот факт, что оба man whichявно говорят, что они не следуют по символическим ссылкам (а мы действительно видим, что это не так, потому which foobarчто не печатает foobar1), а также что документация оболочки POSIX, приведенная выше, никогда не упоминает следующие символические ссылки в PATHалгоритме.
Так, whichа существующие оболочки ошибочны, или я не понимаю документацию?
УТОЧНИТЬ:
Я знаю и могу объяснить существующее поведение. Мой вопрос не «как это работает?». Что я знаю.
Мой вопрос касается документации: где моя ошибка в следовании документации, которую я цитировал. Или документация неверна?
МОТИВАЦИЯ: Почему меня это волнует?
Ну, я реализатор. Различные исполнители предъявляют разные требования. Для меня требование состоит в том, чтобы слово текущего стандарта POSIX ДОЛЖНО сопровождаться ТОЧНО (или, точнее, лучшим, каким оно может быть, потому что сам стандарт несколько глючит). Как будто это было слово Божие.
Теперь стандартная формулировка довольно ясна - следующие символические ссылки не упоминаются, где во многих других местах упоминается, где это необходимо сделать. Так что в этом случае нет.
Однако я всегда дважды проверяю, как dashи как bashсебя вести, просто чтобы убедиться. Теперь, конечно, здесь есть небольшая проблема, dashдаже несмотря на то, что она называется POSIX, имеет множество мелких ошибок, соответствующих POSIX. bashЯ еще не нашел никаких ошибок с POSIX, но ... bash на самом деле не POSIX, это намного больше, чем это.
Так что у вас есть это. Вот почему я забочусь
$PATHнет никаких символических ссылок.
lstat(2)), после них обычно не указывается. Например, в описании open(2)упоминаются только символические ссылки, когда речь идет о поведении O_CREAT | O_EXCL. Не нужно указывать, что целевой файл будет открыт.
$PATHможет содержит символические ссылки. Попробуйwhich sh.