suponha
[root@iz2ze9wve43n2nyuvmsfx5z /]# find . -maxdepth 2 -type d | ls
bin dev home lib64 media opt root sbin sys usr
boot etc lib lost+found mnt proc run srv tmp var
ls não fez nada, como resgate, devo reconstruí-los em uma lista para ls
find . -type d | xargs ls
#millions of outputs
No entanto, o grep faz um bom trabalho
[root@iz2ze9wve43n2nyuvmsfx5z /]# find . -maxdepth 2 -type d | grep home
./home
Como eu poderia distinguir um comando não nasceu como um segundo transmissor da compreensão subjacente em vez de tentar, testar o erro e lembrar.
Ou você aprende e lembra o que os vários programas fazem ou verifica as páginas do manual.
A descrição de
ls
é:onde FILEs se refere à sinopse:
A parte importante a ser lembrada
ls
é que ele gerará informações sobre os "FILEs" que você fornecer - na linha de comando . O manual não descreve nenhuma maneira dels
ler qualquer entrada (por exemplo, um pipe).Compare a
ls
página do manual com, digamos, acat
página do manual, que diz:Com
cat
, você podecat /some/file
ou você podeecho hi | cat
.Portanto, em seu primeiro exemplo,
find
foi e fez algum trabalho e passou alguns (ou nenhum) nomes de diretório em seu stdout, que se tornouls
'stdin, quels
prontamente ignorou. Como vocêls
não forneceu FILEs para listar, o padrão foi listar o diretório atual.No seu segundo exemplo,
find
foi e fez (mais) trabalho, produzindo todos os diretórios encontrados em seu stdout, que por sua vez foi apresentadoxargs
como stdin. A página man paraxargs
leituras, em parte:so then
ls
é chamado quantas vezes forem necessárias, dado o número de linhas de entrada em stdin.A mesma ideia se traduz em seu terceiro comando:
find
passa qualquer nome de diretório paragrep
o stdin de ; A página de manual do grep diz, novamente em parte:A ideia de um pipeline é simples, mas poderosa, e você simplesmente precisa saber que tipo de saída um programa produz e se um programa pode consumir entrada em seu stdin.
grep
é uma das ferramentas mais comuns para usar nessas situações. Você pode usá-lo como o comando principal:nesse caso
grep
sabe os nomes dos arquivos, ou você pode enviar a entrada em seu stdin:... nesse caso, o grep não conhece mais nenhum nome de arquivo (
cat
os conhecia, depois produziu seu conteúdo para stdout), e agora o grep não pode saber quais arquivos continham o texto - apenas quais linhas correspondiam.É tentador encadear um monte de comandos juntos - muitas vezes chamado de "one-liner" muitas vezes semi-facetado, já que um "one-liner" pode se tornar longo o suficiente para envolver duas linhas por segunda em uma janela de terminal - em um "tubulação". Aqui, novamente, você precisa saber exatamente como os programas estão produzindo e consumindo entrada.
Dados os arquivos chamados
file1
,file2
efile3
, você pode fazer algo como:e você não ficará surpreso quando
find
produzir os três nomes de arquivos como stdout --... para o qual xargs compila uma lista e envia para
cat
--... que vê esses três nomes de arquivo e obedientemente despeja seu conteúdo na sua tela.
Cuidado, então, com um arquivo chamado "nome do arquivo aqui"; o comando acima
find
irá produzir:... para o qual o xags compila uma lista para
cat
--... ao qual
cat
reclama (para stderr!):... seguido pelo conteúdo de arquivo1, arquivo2 e arquivo3.
Agora você está preparado para evitar essa situação usando
find ... -exec
ou alternativas comofind ... -print0 | xargs -0 ...
usar NULLs como delimitadores para nomes de arquivos.