A diferença entre * e pipe

0

Dizendo que quero verificar o tamanho de cada arquivo em algum diretório.

Aqui está o que eu faço:

du -sh *

Além disso, posso fazer:

ls | xargs du -sh

Os dois comandos fazem exatamente a mesma coisa.

Eu quero saber se os dois são exatamente iguais, como custo, eficiência etc. (O primeiro comando é mais leve que o segundo, eu acho?)

    
por Yves 25.04.2018 / 11:28

2 respostas

11

Um está correto, o outro não.

du -sh *

(deve ser du -sh -- * para evitar problemas com nomes de arquivos que começam com - )

conta com o shell para expandir o glob * ; du vê todos os arquivos e diretórios não ocultos no diretório atual como argumentos individuais. Isso lida com caracteres especiais corretamente.

ls | xargs du -sh

depende de xargs para processar a saída de ls . xargs divide sua entrada no espaço em branco (pelo menos espaço, tabulação e nova linha, mais com algumas implementações), também compreendendo alguma forma de cotação e executa du (um (mesmo para uma entrada vazia¹) ou mais invocações) a cada única string separada por espaços em branco como argumentos individuais.

Ambos são equivalentes se o diretório atual não contiver arquivos com espaços em branco, aspas simples, aspas duplas ou caracteres de barra invertida em seus nomes e se houver poucos arquivos suficientes (mas pelo menos um) que xargs executem apenas um du invocação, mas não são.

Em termos de eficiência, du -sh * usa um processo, ls | xargs du -sh usa pelo menos três. Há um cenário em que a abordagem de pipe funciona, enquanto a glob não: se você tiver muitos arquivos no diretório atual, o shell não poderá executar du com todos os seus nomes de uma só vez, mas xargs executará du quantas vezes forem necessárias para cobrir todos os arquivos. Nesse caso, você verá várias linhas e os arquivos com mais de um link físico poderão ser contados várias vezes.

Veja também Por que * não * analisar 'ls'?

¹ Se não houver nenhum arquivo não oculto no diretório atual du -sh -- * falhará com um erro do seu shell ou com alguns shells como bash run du com um literal * como argument e du irão reclamar que o arquivo * não existe.

Enquanto com ls | xargs du -sh -- , a maioria xargs implementations (exceções sendo algum BSD) executará du sem argumento e, portanto, o uso de disco do diretório atual (assim também incluindo o uso de disco do próprio arquivo de diretório e todos os arquivos ocultos e diretórios nele)

    
por 25.04.2018 / 12:07
1

No primeiro caso, o shell expande * na lista de nomes de arquivos correspondentes e os transmite como argumentos para o comando du . No segundo caso, o shell inicia dois processos ( ls e xargs ) conectados por meio de um pipe. ls imprime os nomes dos arquivos e xargs os lê, depois inicia o comando du . Então a segunda versão executa 3 comandos, o primeiro apenas um. Existem algumas diferenças potenciais:

  • ls pode listar arquivos em uma ordem diferente
  • dependendo das configurações do ambiente, ls pode até listar mais ou menos arquivos (mas não tenho certeza disso)
  • quando xargs recebe mais nomes de arquivos que podem ser passados como argumentos, ele executará du várias vezes
por 25.04.2018 / 11:44

Tags