No manual do bash , está escrito que
Builtin commands are contained >>> within <<< the shell itself
Além disso, esta resposta afirma que
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 <<<
Quando executo compgen -b
, bash 4.4
recebo uma lista de todos os comandos internos do shell. Eu vejo, por exemplo, isso [
e kill
estão listados como embutidos do shell. Mas suas localizações reais são:
/usr/bin/[
/bin/kill
Eu pensei que ser um builtin
meio que o comando é compilado no /bin/bash
executável. Então, o que realmente está me confundindo: corrija-me, mas como um comando separado pode ser um builtin
, quando na verdade não faz parte do shell?
Os comandos embutidos no shell geralmente são embutidos devido ao aumento de desempenho que isso proporciona. Chamar o external
printf
, por exemplo, é mais lento do que usar o built inprintf
.Como alguns utilitários não precisam ser incorporados, a menos que sejam especiais, como
cd
, eles também são fornecidos como utilitários externos . Isso ocorre para que os scripts não sejam interrompidos se forem interpretados por um shell que não forneça um equivalente integrado.Alguns built-ins do shell também fornecem extensões para o comando equivalente externo. Bash's
printf
, por exemplo é capaz de fazer(imprimir em uma variável) que o externo
/usr/bin/printf
simplesmente não seria capaz de fazer, pois não tem acesso às variáveis do shell na sessão atual do shell (e não pode alterá-las).Os utilitários integrados também não têm a restrição de que sua linha de comando expandida deve ser menor do que um determinado comprimento. Fazendo
é, portanto, seguro se
printf
for um comando interno do shell. A restrição no comprimento da linha de comando vem daexecve()
função da biblioteca C usada para executar um comando externo. Se a linha de comando e o ambiente atual forem maiores queARG_MAX
bytes (vejagetconf ARG_MAX
no shell), a chamada paraexecve()
falhará. Se o utilitário estiver embutido no shell,execve()
não precisa ser chamado.Os utilitários integrados têm precedência sobre os utilitários encontrados nos arquivos
$PATH
. Para desabilitar um comando integrado nobash
, use, por exemploHá uma pequena lista de utilitários que precisam ser construídos em um shell (retirados da lista do padrão POSIX de built-ins especiais )
Eles precisam ser incorporados, pois manipulam diretamente o ambiente e o fluxo do programa da sessão atual do shell. Um utilitário externo não seria capaz de fazer isso.
Curiosamente,
cd
não faz parte desta lista, mas o POSIX diz o seguinte sobre isso:Portanto, estou assumindo que os built-ins "especiais" não podem ter contrapartes externas, enquanto
cd
em teoria poderiam ter (mas não faria muito).Você está (compreensivelmente) confuso com o fato de que alguns builtins existem tanto como builtins quanto como comandos externos. Portanto, embora você esteja certo de que, por exemplo, existe um
/bin/[
comando, isso não significa que sua "localização real" esteja em/bin
.Qualquer maneira fácil de testar isso é executar
type
com o-a
switch que mostrará todas as instâncias disponíveis de um comando. No meu sistema Arch, isso mostra:Observe que
/sbin
,/usr/sbin
e/bin
todos os links simbólicos apontam para/usr/bin
, portanto, há apenas um externo[
:Como você pode ver,
[
é um comando interno e externo, e o mesmo é verdade para vários outros comandos internos do shell. No entanto, isso não muda o fato de que eles também são internos do shell, compilados no próprio shell.