Entendendo como as entradas são enviadas para pipes no Bash

17

Eu não entendo muito bem como os pipes funcionam no bash.

Eu sei que é preciso uma saída de um comando como a entrada em outro comando.

Qual é a saída que posso obter porque é o que o comando imprime na tela.

Mas como eu sei qual entrada um comando levará?

Aqui está um exemplo que pensei que funcionaria:

which gem | rm

Infelizmente isso não aconteceu.

Qual gema imprime /usr/bin/gem , então essa deve ser a saída correta?

Eu achei que foi dado para rm, então seria rm /usr/bin/gem , mas eu estava errado.

Então, minha pergunta é: como sei qual entrada um comando leva?

    
por ajsie 21.08.2010 / 04:56

4 respostas

23

"Entrada" e "argumentos da linha de comando" são coisas diferentes.

rm remove os arquivos fornecidos como argumentos.

Um canal redireciona a saída do comando à esquerda para a entrada do comando à direita. Não afeta os argumentos da linha de comando do programa à direita.

Para fazer o que você está tentando fazer, tente usar xargs para converter a entrada padrão em argumentos de linha de comando para executar um programa. Esse é o seu trabalho.

which gem | xargs rm , por exemplo, removerá o gem no seu PATH.

    
por 21.08.2010 / 05:00
12

rm não recebe entrada, recebe argumentos. Estes são diferentes. Argumentos são os comutadores e nomes de arquivos e assim por diante que você fornece a um programa na linha de comandos para afetar seu comportamento. Entrada são os dados em que o programa funciona. Por exemplo, grep aceita entrada e argumentos:

grep "foo" file.txt

Existem dois argumentos "foo" e file.txt . A entrada é o conteúdo de file.txt , não a string file.txt em si. Como o grep recebe dados, você pode usá-lo com pipes:

cat file.txt | grep "foo"

produz a mesma saída, uma vez que cat está aceitando file.txt como argumento e produzindo o conteúdo de file.txt como saída. Essa saída é então canalizada para o grep, dando o mesmo efeito de ter o grep aberto, como no primeiro exemplo.

Se você quiser usar a saída de um programa como o argumento para outro, use backticks:

rm 'which gem'

ou esta sintaxe alternativa (específica do bash):

rm $(which gem)

Editar: ou xargs como outro respondente aponta. Muitas maneiras de esfolar um gato com uma linha de comando.

    
por 21.08.2010 / 05:02
3

Confira as man páginas de comandos nos quais você está interessado. Esses programas indicarão que eles leram stdin (tente man grep para um comando popular que leia stdin).

    
por 21.08.2010 / 04:59
2

Estes são todos perigosos para serem executados se você tiver um diretório em seu PATH que contenha espaço ou se o nome do comando contiver espaço:

rm 'which gem'       # Dangerous
rm $(which gem)      # Dangerous
which gem | xargs rm # Dangerous

GNU Parallel http: // www.gnu.org/software/parallel/ não tem isso problema, então isso funcionará mesmo se você tiver um diretório em seu PATH que contenha espaço ou se o nome do comando contiver espaço:

which gem | parallel rm
parallel -a <(which bass) rm

Assista ao vídeo de introdução do GNU Parallel: link

    
por 22.08.2010 / 21:52

Tags