Por que existe um / bin / echo e por que eu desejaria usá-lo?

46

Notei que existe um executável binário /bin/echo no meu sistema Ubuntu MATE 17.04.

Eu achei estranho, porque

$ type echo
echo is a shell builtin

O teste de rastreamento sugere que /bin/echo faz o mesmo tipo de coisa que o Bash incorporado em echo :

$ /bin/echo foo
foo
$ /bin/echo $USER
zanna

Então, por que há outra versão de echo separada do programa Bash, e por que ou quando eu iria querer usá-la?

    
por Zanna 30.09.2017 / 17:46

2 respostas

84

Se você abrir um prompt bash e digitar um O comando echo , que usa um shell embutido em vez de executar /bin/echo . As razões pelas quais ainda é importante que /bin/echo existam são:

  1. Você nem sempre está usando um shell. Em várias circunstâncias, você executa um executável diretamente e não através de um shell.
  2. Pelo menos em teoria, alguns shells não possuem um echo embutido. Isso não é realmente necessário.

Para expandir # 1, suponha que você queira mover todos os arquivos regulares cujos nomes começaram com abc em qualquer lugar em src to dest . Existem várias maneiras de fazer isso, mas uma delas é:

find src -name 'abc*' -type f -exec mv -nv {} dest/ \;

Mas suponha que, em vez de apenas executar isso, você deseje ver todos os comandos que serão executados primeiro. Bem, então você pode prefixar echo no comando, assim como você poderia em outros contextos:

find src -name 'abc*' -type f -exec echo mv -nv {} dest/ \;

Mas find não usa um shell. Isso é executado /bin/echo .

Além de find com -exec ou -execdir , o executável /bin/echo será chamado por outros programas que executem programas, mas não por meio de um shell. Este acontece com o xargs (que está relacionado a find ) , bem como em vários outros contextos, como Exec= line de um arquivo .desktop . Outro exemplo é quando você executa sudo echo , o que pode ser útil para testar se sudo está funcionando.

Da mesma forma, alguns shells possuem um printf embutido, mas /usr/bin/printf também existe.

Um motivo menos comum possível que você pode usar deliberadamente /bin/echo é se você estava confiando nas diferenças entre ele e o comando echo fornecido pelo seu shell. man echo documentos /bin/echo ; help echo in bash documenta o bash construído. echo não é muito portável, porque implementações diferentes - tanto em sistemas operacionais quanto em shells no mesmo sistema operacional - suporta diferentes opções (por exemplo, -e ) e diferem no tratamento de barras invertidas . Claro, é melhor evitar confiar em tais detalhes e usar printf em vez disso, que é muito mais portátil .

Em bash , você pode tornar o type builtin show /bin/echo também - assumindo que /bin está em sua $PATH como sempre deveria ser - por passando o símbolo -a :

$ type -a echo
echo is a shell builtin
echo is /bin/echo
    
por Eliah Kagan 30.09.2017 / 17:55
30

Eliah fez um ótimo trabalho ao responder isso, mas quero comentar sobre a parte "por que há outra versão do echo separado do programa Bash". Essa é a pergunta errada.

A pergunta certa é: por que isso é feito em primeiro lugar , quando poderia ter sido ( e é) um comando externo perfeitamente bom?

Para simplificar, dê uma olhada no built in in dash, um mísero 38 (bash tem 61, para comparação, passando pela saída de compgen -b ):

.               continue        getopts         readonly        type
:               echo            hash            return          ulimit
[               eval            jobs            set             umask
alias           exec            kill            shift           unalias
bg              exit            local           test            unset
break           export          printf          times           wait
cd              false           pwd             trap
command         fg              read            true

Quantos desses precisam ser construídos? [ , echo , false , printf , pwd , test e true não precisam para serem internos: eles não fazem nada que somente um builtin pode fazer (afetar ou obter o estado do shell que não está disponível para comandos externos). O printf do Bash, pelo menos, aproveita-se de ser incorporado: printf -v var salva a saída para a variável var . time no bash também é especial: por ser uma palavra-chave, você pode cronometrar listas de comandos arbitrárias no bash (o traço não tem um time equivalente). pwd também não precisa ser construído - qualquer comando externo herdará o diretório de trabalho atual (e é um comando externo também). : é uma exceção - você precisa de um NOP e : é isso. O resto faz ações que um comando externo pode fazer facilmente.

Portanto, um quinto desses recursos internos não precisa ser construído. Porquê então? A dash manpage * na verdade explica de passagem porque estas são builtins (ênfase meu):

Builtins
 This section lists the builtin commands which are builtin because they
 need to perform some operation that can't be performed by a separate
 process.  In addition to these, there are several other commands that may
 be builtin for efficiency (e.g.  printf(1), echo(1), test(1), etc).

Isso é muito bonito: esses recursos internos estão lá porque são usados com tanta freqüência, interativamente e em scripts, e sua funcionalidade é simples o suficiente, que o shell pode fazer o trabalho. E assim acontece: alguns (mais?) Shells aceitaram o trabalho. ** Volte para o sh de 2.9 BSD , e você não encontrará um echo embutido.

Assim, é perfeitamente possível que um shell mínimo possa pular a implementação de comandos como builtins (não acho que qualquer shell atual, no entanto). O projeto GNU coreutils não assume que você irá executá-los em um shell específico, e POSIX requer estes comandos. Então, o coreutils fornece isso de qualquer maneira, e pula aqueles que não têm nenhum significado fora do shell.

* Isso é quase idêntico a o texto de manpage correspondente para o shell Almquist , que é o que se baseia no dash, o shell do Almquist Debian.

** zsh leva essa idéia ao extremo: os comandos que você obtém carregando vários módulos, como zmv , são coisas que você não acha que um shell precisa entrar em . Nesse ponto, a verdadeira questão é: por que você usaria o bash em vez do zsh, que possui todos esses recursos internos?

    
por muru 30.09.2017 / 22:19