Por que echo é um shell construído em comando?

34
$ 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?

    
por Lazer 29.08.2010 / 09:33

6 respostas

71

Existem duas classes de builtins:

  1. Alguns comandos precisam ser construídos no próprio programa shell, porque eles não podem funcionar se forem externos.

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

  2. A outra classe de comandos é embutida no shell apenas por eficiência.

    O dash man page tem uma seção no builtins que menciona printf , echo e test como exemplos de comandos nesta classe.

Os sistemas Unix sempre incluíram executáveis separados para comandos nessa segunda classe. Esses executáveis separados ainda estão disponíveis em todos os sistemas Unixy que eu usei, mesmo que eles também estejam incorporados em todos os shell que você provavelmente usará. ( POSIX na verdade requer que esses executáveis estejam presentes.)

Acredito que echo foi incorporado 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 & sistemas Unix da série 3B1 . Alguém gentilmente digitalizou as edições de 1986 desses manuais e as colocou online ; estes correspondem ao lançamento original do SVR3. Você pode ver que echo não está na lista na página 523 do Manual do Usuário do UNIX System V, Volume II , onde você esperaria se o comando estivesse embutido no shell. Na minha cópia em papel local dos manuais do SVR3.1 de 1987, echo é listado nesta seção do manual.

Tenho certeza de que esta não é uma inovação da Berkeley CSRG que a AT & T trouxe para casa. 4.3BSD saiu no mesmo ano que SVR3, 1986, mas se você olhar para 4.3BSD's sh.1 manpage , você vê que echo não está na lista da seção "Special Commands" dos comandos internos. Se o CSRG fez isso, isso nos deixa querendo uma fonte documentada para provar isso.

Neste ponto, você pode se perguntar se echo foi construído no shell antes do SVR3.1 e que este fato simplesmente não foi documentado até então. O mais novo código fonte pré-SVR3 AT & T Unix disponível para mim está no PDA do sistema III do PDP-11 , onde você encontrará o código fonte do shell Bourne. Você não encontrará echo na tabela de comandos incorporada, que está em /usr/src/cmd/sh/msg.c . Com base nos timestamps desse 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 de ponto para essa pergunta, mas encontramos 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..
*/      
    
por 29.08.2010 / 12:32
19

Existe uma terceira razão para alguns comandos serem incorporados: Eles podem ser usados quando executar comandos externos é impossível.

Às vezes, um sistema fica tão corrompido 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 será possível executar /bin/kill (porque ele precisa de um PID :-), mas o% co_de interno % funcionará.

Btw., kill é um comando externo (pelo menos não é interno no bash), portanto, ele não pode listar comandos internos. Por exemplo:

$ which echo
/bin/echo
$ type -a echo
echo is a shell builtin
echo is /bin/echo
    
por 22.09.2010 / 23:51
13

De acordo com o Manual de referência do Bash , é sobre conveniência.

Shells also provide a small set of built-in commands (builtins) implementing functionality impossible or inconvenient to obtain via separate utilities. For example, cd, break, continue, and exec) cannot be implemented outside of the shell because they directly manipulate the shell itself. The history, getopts, kill, or pwd builtins, among others, could be implemented in separate utilities, but they are more convenient to use as builtin commands. All of the shell builtins are described in subsequent sections.

O Guia avançado de scripts de bash tem uma explicação mais detalhada:

"A builtin is a command contained within the Bash tool set, literally built in. This is either for performance reasons -- builtins execute faster than external commands, which usually require forking off 1 a separate process -- or because a particular builtin needs direct access to the shell internals."

Observe também que echo existe como um utilitário autônomo em alguns sistemas. Aqui está o que eu 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 um arquivo embutido, mas aparentemente meus scripts usam / bin / echo no meu Mac e usam um Bash embutido na maioria dos meus Linux & Sistemas FreeBSD. Mas isso não parece importar, porque os scripts ainda funcionam bem em todos os lugares.

    
por 30.08.2010 / 19:11
6

Para complementar a resposta da bhm, digamos que /bin foi acidentalmente removido do seu PATH . Você gostaria de poder echo $PATH descobrir isso, certo?

    
por 20.10.2011 / 12:49
2

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

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

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

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

    
por 30.08.2010 / 15:29
1

Aqui está o verdadeiro motivo pelo qual echo deve ser um shell embutido:

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

echo "$PASSWORD" >./password

No entanto, se echo não fosse um shell incorporado, a senha vazaria para todos os usuários por meio de ps information.

Claro, se você quer ser esperto, você pode encontrar uma maneira de armazenar uma senha sem echo , talvez explorando algum outro recurso de shell:

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

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

    
por 19.02.2017 / 06:20