Из этого вопроса о том, является ли printf встроенным для yash , следует ответ, который цитирует стандарт POSIX .
Ответ указывает на то, что последовательность поиска POSIX должна найти внешнюю реализацию желаемой команды, а затем, если оболочка реализовала ее как встроенную, запустить встроенную. (Для встроенных модулей, которые не являются специальными встроенными модулями .)
Почему POSIX имеет это требование для существования внешней реализации, прежде чем разрешить запуск внутренней реализации?
Это кажется ... произвольным, поэтому мне любопытно.
shell
posix
shell-builtin
studog
источник
источник
printf
.PATH
и затем вызывать встроенную утилиту, а не внешний скрипт. Что если вы захотите вызвать внешний скрипт на вашем пути? Хм ... Кажется, это требует таблицы с описанием различных возможностей. Существует одна здесь , но это не имеет смысла для меня.Ответы:
Это правило «как будто».
Проще говоря: поведение оболочки в том виде, в каком ее видят пользователи, не должно меняться, если реализация решит сделать стандартную внешнюю команду также доступной в качестве встроенной оболочки.
Контраст, который я показал на /unix//a/496291/5132, между поведением (с одной стороны) оболочек PD Korn, MirBSD Korn и Heirloom Bourne; (с другой стороны) оболочки Z, 93 Korn, Bourne Again и Debian Almquist; и (на захватной руке) оболочка Ватанабэ подчеркивает это.
Для оболочек, которые не имеют
printf
встроенной функции, удаление/usr/bin
изPATH
вызывает вызовprintf
прекращения работы. Поведение, соответствующее POSIX, демонстрируемое оболочкой Watanabe в ее режиме, приводит к тому же результату. Поведение оболочки, имеющейprintf
встроенную функцию, выглядит так, как будто она вызывает внешнюю команду.Принимая во внимание, что поведение всех несовместимых оболочек не изменяется, если
/usr/bin
удаляется изPATH
, и они не ведут себя так, как если бы они вызывали внешнюю команду.Стандарт пытается гарантировать вам, что оболочки могут встраивать всевозможные обычно внешние команды (или реализовывать их как свои собственные функции оболочки), и вы по-прежнему будете вести себя так же, как и встроенные. с внешними командами, если вы настраиваете,
PATH
чтобы остановить команды от поиска.PATH
остается вашим инструментом для выбора и управления, какие команды вы можете вызвать.(Как объяснено на /unix//a/448799/5132 , несколько лет назад люди выбирали индивидуальность своего Unix, изменяя то, что было включено
PATH
.)Можно предположить, что выполнение команды всегда работает независимо от того, где она может быть найдена, на
PATH
самом деле является целью встроить обычно внешние команды. (Именно поэтому мой набор инструментов nosh только что получил встроеннуюprintenv
команду в версии 1.38. На самом деле это не оболочка.)Но стандарт дает вам гарантию того, что для обычных внешних команд, которые не включены в оболочку , вы увидите то же поведение, что и в
PATH
других не-оболочечных программах, вызывающихexecvpe()
функцию, и оболочка не сможет волшебным образом запускать (очевидно) обычные внешние команды, которые другие программы не могут найти с тем жеPATH
. Все работает самосогласованно с точки зрения пользователя иPATH
является инструментом для управления его работой.дальнейшее чтение
источник
Это довольно абсурдно, и поэтому ни одна оболочка не реализует его в режиме по умолчанию.
Обоснование стандарта и его иллюстрирующий пример предполагают, что это была неудачная попытка иметь регулярную встроенную функцию, связанную с путем, и позволить пользователю переопределить ее, представив свой собственный двоичный файл перед ним
PATH
(например,printf
встроенную функцию, связанную с/usr/bin/printf
может быть отменено/foo/bin/printf
внешней командой путем установкиPATH=/foo/bin:$PATH
).Однако стандарт не требовал этого, но что-то совершенно иное (а также бесполезное и неожиданное).
Вы можете прочитать больше об этом в этом сообщении об ошибке . Цитата из окончательного принятого текста :
FWIW, я не думаю, что есть какая-либо оболочка, реализующая пересмотренные требования из принятого текста, либо.
источник
/usr/bin/printf
или/foo/bin/printf
в PATH активирует встроенный printf. Единственное, чтоprintf
будет делать отсутствующий (в PATH) внешний - это отключить встроенную функцию. (По букве спецификации).