Команды, встроенные в оболочку, часто встроены из-за увеличения производительности, которое это дает. Например, внешний вызов printf
выполняется медленнее, чем встроенный printf
.
Поскольку некоторые утилиты не нужно встраивать, если они не являются специальными, например cd
, они также предоставляются в качестве внешних утилит. Это делается для того, чтобы сценарии не ломались, если они интерпретируются оболочкой, которая не предоставляет встроенный эквивалент.
Некоторые встроенные функции оболочки также предоставляют расширения для внешней эквивалентной команды. Баш printf
, например, умеет делать
$ printf -v message 'Hello %s' "world"
$ echo "$message"
Hello world
(вывод в переменную), что внешнее /usr/bin/printf
просто не сможет сделать, так как у него нет доступа к переменным оболочки в текущем сеансе оболочки (и они не могут их изменить).
Встроенные утилиты также не имеют ограничения, что их расширенная командная строка должна быть короче определенной длины. дела
printf '%s\n' *
Поэтому безопасно, если printf
это встроенная команда оболочки. Ограничение длины командной строки исходит из execve()
функции библиотеки C, используемой для выполнения внешней команды. Если командная строка и текущая среда больше ARG_MAX
байтов (см. getconf ARG_MAX
В оболочке), вызов execve()
завершится ошибкой. Если утилита встроена в оболочку, execve()
вызывать не нужно.
Встроенные утилиты имеют приоритет над утилитами, найденными в $PATH
. Чтобы отключить встроенную команду bash
, используйте, например,
enable -n printf
Существует небольшой список утилит, которые необходимо встроить в оболочку (взят из списка специальных встроенных модулей стандарта POSIX )
break
colon (:)
continue
dot (.)
eval
exec
exit
export
readonly
return
set
shift
times
trap
unset
Они должны быть встроены, так как они напрямую управляют средой и потоком программы текущего сеанса оболочки. Внешняя утилита не сможет этого сделать.
Интересно, cd
что не входит в этот список, но POSIX говорит об этом следующее :
Поскольку cd
влияет на текущую среду выполнения оболочки, она всегда предоставляется как обычная встроенная оболочка. Если он вызывается в подоболочке или в отдельной среде выполнения утилит, например, одной из следующих:
(cd /tmp)
nohup cd
find . -exec cd {} \;
это не влияет на рабочий каталог среды вызывающего.
Поэтому я предполагаю, что «специальные» встроенные модули не могут иметь внешних аналогов, в то время как cd
теоретически могут иметь (но это не очень поможет).