web-development-kb-pt.site

Por que o echo é um comando embutido?

$ which echo
echo: Shell built-in command.
$ which ls
/bin/ls
$ which cat
/bin/cat

Por que o echo não é um utilitário independente como ls, ps, cat etc? Por que é específico do Shell? Alguma boa razão?

35
Lazer

Existem duas classes de builtins:

  1. Alguns comandos devem ser integrados ao próprio programa Shell, porque não funcionarão se forem externos.

    cd é um desses porque, se fosse externo, só poderia mudar seu próprio diretório; não poderia afetar o diretório de trabalho atual do Shell. (Veja também: Por que cd não é um programa? )

  2. A outra classe de comandos é construída no Shell exclusivamente para eficiência.

    O dashpágina man tem uma seção sobre os builtins que menciona printf, echo e test como exemplos de comandos nesta classe.

Os sistemas Unix sempre incluíram executáveis ​​separados para comandos dessa segunda classe. Esses executáveis ​​separados ainda estão disponíveis em todos os sistemas Unixy que usei, embora também estejam integrados a todos os Shell que você provavelmente usará. ( POSIX realmente requer que esses executáveis ​​estejam presentes.)

Eu acredito que echo foi integrado ao Shell no AT&T Unix System V Release 3.1. Eu baseio isso em comparações de duas edições diferentes de manuais para AT&T sistemas Unix da série 3B1 . Alguém gentilmente digitalizou as edições de 1986 desses manuais e coloque-os online ; eles correspondem à versão original do SVR3. Você pode ver que echo não está na lista na página 523 de UNIX System V Manual do Usuário, Volume II , onde você esperaria se o comando fosse embutido no Shell. Na minha cópia impressa local dos manuais SVR3.1 de 1987, echo está listado nesta seção do manual.

Tenho certeza que não é Berkeley CSRG inovação que a AT&T trouxe de volta para casa. 4.3BSD foi lançado no mesmo ano que SVR3, 1986, mas se você olhar em página man sh.1 do 4.3BSD , você verá que echo não está na lista da seção "Comandos Especiais" de comandos integrados. Se o CSRG fez isso, ficamos querendo uma fonte documentada para provar isso.

Neste ponto, você pode se perguntar se echo foi construído no Shell antes de SVR3.1 e que esse fato simplesmente não foi documentado até então. O mais novo código-fonte Unix pré-SVR3 AT&T disponível para mim está no tarball PDP-11 System III , onde você encontrará o código-fonte do Bourne Shell. Você não encontrará echo na tabela de comandos embutida, que está em /usr/src/cmd/sh/msg.c. Com base nos carimbos de data/hora nesse arquivo, isso prova que echo certamente não estava no Shell em 1980.


Curiosidades

O mesmo diretório também contém um arquivo chamado builtin.c que não contém nada específico para esta questão, mas achamos este comentário interessante:

/*      
    builtin commands are those that Bourne did not intend
    to be part of his Shell.
    Redirection of i/o, or rather the lack of it, is still a
    problem..
*/      
72
Warren Young

Há um terceiro motivo para alguns comandos serem integrados: Eles podem ser usados ​​quando a execução de comandos externos é impossível.

Às vezes, um sistema fica tão danificado que o comando ls não funciona. Em alguns casos, um echo * ainda funcionará.

Outro exemplo (mais importante!) É kill: Se um sistema ficar sem PIDs livres, não é possível executar /bin/kill (porque precisa de um PID :-), mas o kill embutido funcionará.

A propósito, which é um comando externo (pelo menos não é interno no bash), portanto, não pode listar comandos internos. Por exemplo:

$ which echo
/bin/echo
$ type -a echo
echo is a Shell builtin
echo is /bin/echo
19
bhm

De acordo com o Manual de referência do Bash , trata-se de conveniência.

Os shells também fornecem um pequeno conjunto de comandos embutidos (embutidos) que implementam funcionalidades impossíveis ou inconvenientes de obter por meio de utilitários separados. Por exemplo, cd, break, continue e exec) não podem ser implementados fora do Shell porque manipulam diretamente o próprio Shell. Os builtins history, getopts, kill ou pwd, entre outros, podem ser implementados em utilitários separados, mas são mais convenientes de usar como comandos embutidos. Todos os builtins do Shell são descritos nas seções subsequentes.

O Advanced Bash Scripting Guide tem uma explicação mais detalhada:

"Um embutido é um comando contido no conjunto de ferramentas Bash, literalmente embutido. Isso ocorre por motivos de desempenho - os embutidos são executados mais rapidamente do que os comandos externos, que geralmente exigem bifurcação 1 um processo separado - ou porque um determinado builtin precisa de acesso direto aos internos do Shell. "

Observe também que echo existe como um utilitário autônomo em alguns sistemas. Aqui está o que tenho no meu sistema Darwin (MacOSX 10.5.8 - Leopard)

$ uname -a
Darwin Host.foo.org 9.8.0 Darwin Kernel Version 9.8.0: Wed Jul 15 16:55:01 PDT 2009; root:xnu-1228.15.4~1/RELEASE_I386 i386
$ bash --version
GNU bash, version 3.2.17(1)-release (i386-Apple-darwin9.0)
Copyright (C) 2005 Free Software Foundation, Inc.
$ which echo
/bin/echo

echo também está disponível como embutido, mas aparentemente meus scripts usam/bin/echo no meu Mac e usam um Bash embutido na maioria dos meus sistemas Linux e FreeBSD. Mas isso não parece importar, porque os scripts ainda funcionam bem em qualquer lugar.

13
Stefan Lasiewski

Para complementar a resposta de bhm, digamos /bin foi acidentalmente removido de seu PATH. Você gostaria de ser capaz de echo $PATH para descobrir isso, certo?

6
Daniel Hershcovich

Embora a maioria dos shells inclua um echo embutido hoje em dia, o GNU CoreUtils também inclui uma implementação autônoma dele:

$ which echo
/bin/echo
$ dpkg -S /bin/echo
coreutils: /bin/echo

Parece que você não tem GNU Coreutils instalado (a maioria dos sistemas operacionais de desktop e servidor baseados em Linux o tem instalado por padrão, mas o Linux embutido ou outro UNIX pode usar coleções alternativas de utilitários Shell) .

BTW: se você olhar em Busybox , você verá que ls, ps e cat também são comandos embutidos lá (ou em menos pode ser; é usado para sistemas integrados e tudo o que não é necessário pode ser deixado de fora).

2
JanC

Aqui está o verdadeiro motivo pelo qual echo deve ser um Shell integrado:

Suponha que você tenha uma senha em $PASSWORD. Como você grava em um arquivo ./password? Naturalmente, a maioria dos programadores escreveria:

echo "$PASSWORD" >./password

No entanto, se echo não fosse um Shell embutido, a senha vazaria para todos os usuários por meio de informações de ps.

Claro, se você quiser ser mais esperto, pode encontrar uma maneira de armazenar uma senha sem echo, talvez explorando algum outro recurso do Shell:

cat >./password <<EOF
${PASSWORD}
EOF

No entanto, ter echo embutido é um cinto de segurança importante, pois a maneira mais óbvia de salvar uma senha em um arquivo também deve funcionar.

1
DepressedDaniel