В руководстве по bash написано, что
Builtin commands are contained >>> within <<< the shell itself
Кроме того, этот ответ гласит, что
A built-in command is simply a command that the shell carries out itself,
instead of interpreting it as a request to load and run some
>>> other program <<<
Когда я бег compgen -b
на bash 4.4
, я получаю список всех оболочки встроены командами. Я вижу, например, что [
и kill
перечислены как встроенные оболочки. Но их фактическое местоположение:
/usr/bin/[
/bin/kill
Я думал, что это builtin
означает, что команда скомпилирована в /bin/bash
исполняемый файл. Итак, что меня действительно смущает: пожалуйста, исправьте меня, но как может быть отдельная команда builtin
, если она на самом деле не является частью оболочки?
bash
shell
shell-builtin
manifestor
источник
источник
exec
для манипулирования дескрипторами файлов иeval
для оценки команд. Они не нужны как отдельные командыОтветы:
Команды, встроенные в оболочку, часто встроены из-за увеличения производительности, которое это дает. Например, внешний вызов
printf
выполняется медленнее, чем встроенныйprintf
.Поскольку некоторые утилиты не нужно встраивать, если они не являются специальными, например
cd
, они также предоставляются в качестве внешних утилит. Это делается для того, чтобы сценарии не ломались, если они интерпретируются оболочкой, которая не предоставляет встроенный эквивалент.Некоторые встроенные функции оболочки также предоставляют расширения для внешней эквивалентной команды. Баш
printf
, например, умеет делать(вывод в переменную), что внешнее
/usr/bin/printf
просто не сможет сделать, так как у него нет доступа к переменным оболочки в текущем сеансе оболочки (и они не могут их изменить).Встроенные утилиты также не имеют ограничения, что их расширенная командная строка должна быть короче определенной длины. дела
Поэтому безопасно, если
printf
это встроенная команда оболочки. Ограничение длины командной строки исходит изexecve()
функции библиотеки C, используемой для выполнения внешней команды. Если командная строка и текущая среда большеARG_MAX
байтов (см.getconf ARG_MAX
В оболочке), вызовexecve()
завершится ошибкой. Если утилита встроена в оболочку,execve()
вызывать не нужно.Встроенные утилиты имеют приоритет над утилитами, найденными в
$PATH
. Чтобы отключить встроенную командуbash
, используйте, например,Существует небольшой список утилит, которые необходимо встроить в оболочку (взят из списка специальных встроенных модулей стандарта POSIX )
Они должны быть встроены, так как они напрямую управляют средой и потоком программы текущего сеанса оболочки. Внешняя утилита не сможет этого сделать.
Интересно,
cd
что не входит в этот список, но POSIX говорит об этом следующее :Поэтому я предполагаю, что «специальные» встроенные модули не могут иметь внешних аналогов, в то время как
cd
теоретически могут иметь (но это не очень поможет).источник
chdir
/cd
были внешними двоичными файлами в очень ранних версиях Unix / pre-Unix до того, какfork
был представлен./usr/bin/cd
, но на самом деле он не изменит текущий рабочий каталог. Его руководство гласит:/usr/bin/cd
не влияет на процесс вызова, но может использоваться для определения, может ли данный каталог быть установлен в качестве текущего каталога.kill
также хороша, потому что ей не нужно форкать другой процесс, хорошо, если вы достигли ограничения по количеству процессов.Вы (очень понятно) смущает тот факт , что некоторые встроенные функции существуют как в качестве встроенных команд и в качестве внешних команд. Итак, хотя вы правы в том, что, например, есть
/bin/[
команда, это не значит, что ее «фактическое местоположение» находится в/bin
.Любой простой способ проверить это - запустить
type
с-a
переключателем, который покажет все доступные экземпляры команды. В моей системе Arch это показывает:Обратите внимание , что
/sbin
,/usr/sbin
и/bin
все символические ссылки , указывающие/usr/bin
, так что есть только один внешний[
:Как вы можете видеть,
[
это как встроенная, так и внешняя команда, и то же самое верно для различных других встроенных команд оболочки. Однако это не меняет того факта, что они также являются встроенными в оболочку, скомпилированными в саму оболочку.источник
/bin/printf
устанавливается наcoreutils
корпусе и/bin/kill
наutil-linux
.