Как оболочка решает, какую из ключевых слов, встроенных и внешних команд запускать?

Когда есть встроенное имя, ключевое слово и / или внешняя команда с одинаковым именем, каков порядок, в котором оболочка Bash решает запустить?

Например,

  • time ключевого слова и time внешней команды,
  • встроенный printf и внешняя команда printf от coreutils.

Из справочного руководства GNU Bash :

После того, как команда была разделена на слова, если она приводит к простой команде и необязательному списку аргументов, предпринимаются следующие действия.

  1. Если имя команды не содержит косой черты, оболочка пытается найти ее. Если для этого имени существует функция оболочки, эта функция вызывается, как описано в « Функции оболочки» .

  2. Если имя не соответствует функции, оболочка ищет ее в списке встроенных оболочек. Если найдено совпадение, вызывается эта встроенная функция.

  3. Если имя не является ни функцией оболочки, ни встроенным, и не содержит косых черт, Bash ищет каждый элемент из $PATH для каталога, содержащего исполняемый файл с этим именем. Bash использует хеш-таблицу для запоминания полных путей к исполняемым файлам, чтобы избежать множественных поисков PATH (см. Описание хеша в Bourne Shell Builtins ). Полный поиск каталогов в $PATH выполняется только в том случае, если команда не найдена в хеш-таблице. Если поиск не увенчался успехом, оболочка ищет определенную функцию оболочки с именем command_not_found_handle . Если эта функция существует, она вызывается с исходной командой и аргументами исходной команды в качестве ее аргументов, а статус выхода функции становится статусом выхода оболочки. Если эта функция не определена, оболочка печатает сообщение об ошибке и возвращает статус выхода 127.

  4. Если поиск выполняется успешно или если имя команды содержит одну или несколько косой черты, оболочка выполняет именованную программу в отдельной среде исполнения. Аргумент 0 устанавливается на указанное имя, а остальные аргументы команды устанавливаются в поставляемые аргументы, если они есть.

  5. Если это выполнение не выполняется, поскольку файл не находится в исполняемом формате, а файл не является каталогом, предполагается, что он является скриптом оболочки, а оболочка выполняет его, как описано в Shell Scripts .

  6. Если команда не была запущена асинхронно, оболочка ожидает завершения команды и собирает ее статус выхода.

В случае конфликтов имен bash сначала попытается вызвать команду builtin. Я сделал следующий тест.

 time sleep 100 & ps -ef | grep [t]est 

Внешняя команда должна создать новый процесс, но вы увидите, что результата не было. Это означает, что вызывается команда builtin.