Стандарт оболочки 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
.