На цьому сайті пише стандарт оболонки 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
.