Como canalizar saída de comando para outros comandos?

78

Exemplo:

ls | echo não imprime nada (uma linha em branco, na verdade). Eu esperaria que ele imprimisse uma lista de arquivos.

ls | grep 'foo' , por outro lado, funciona como esperado (imprime arquivos com 'foo' em seu nome).

O que eu faço nessas situações é algo como:       ls | while read OUT; do echo $OUT; done , mas isso é um pouco complicado.

Por que a tubulação funciona com alguns comandos, mas não com outros? Como posso contornar esse problema?

    
por Mihai Rotaru 16.09.2010 / 15:40

4 respostas

109

Existe uma distinção entre argumentos de linha de comando e entrada padrão. Um tubo conectará a saída padrão de um processo à entrada padrão de outro. Então

ls | echo

Conecta a saída padrão de ls à entrada padrão do eco. Bem certo? Bem, echo ignora a entrada padrão e despejará seus argumentos de linha de comando - que neste caso não são nenhum - para seu próprio stdout. A saída: nada mesmo.

Existem algumas soluções neste caso. Uma delas é usar um comando que leia stdin e dumps para stdout, como cat.

ls | cat

Vai 'funcionar', dependendo da sua definição de trabalho.

Mas e sobre o caso geral. O que você realmente quer é converter stdout de um comando em argumentos de linha de comando de outro. Como outros disseram, xargs é a ferramenta auxiliar canônica nesse caso, lendo seus argumentos de linha de comando para um comando de seu stdin e construindo comandos para executar.

ls | xargs echo

Você também pode converter isso, usando o comando de substituição $()

echo $(ls)

Também faria o que você quer.

Ambas as ferramentas são básicas para o shell de scripts, você deve aprender as duas coisas.

Para completar, como você indica na pergunta, a outra forma básica de converter stdin em argumentos de linha de comando é o comando read embutido do shell. Ele converte "palavras" (palavras definidas pela variável IFS ) em uma variável temporária, que você pode usar em qualquer execução de comando.

    
por 16.09.2010 / 16:16
16

ls | echo imprime apenas uma linha em branco porque echo não lê nenhuma entrada; o último comando do pipeline é, na verdade, echo , que não imprime nada além de uma linha em branco.

Geralmente:

a | b

garante que a saída de a se torne a entrada de b . Eu sugiro que você leia a seção Pipelines de man bash .

Se você realmente quiser usar ls e echo juntos, aqui estão alguns exemplos (bem inúteis):

ls | xargs -L 1 echo
echo 'ls'
for i in 'ls' ; do echo $i ; done
    
por 16.09.2010 / 15:54
7

Se você deseja echo o comando ls , tente:

ls | xargs echo

Isso chamará echo com a saída de ls .

    
por 16.09.2010 / 16:03
3

Por que não usar simplesmente:

echo 'ls'

Ou muito mais seguro:

echo "'ls -lrt'"
    
por 09.11.2011 / 10:48

Tags