encontrar -exec + vs encontrar | xargs: qual escolher?

encontrar -exec + vs encontrar | xargs: qual escolher?

Eu entendo que eles -execpodem optar +por imitar o comportamento de xargs. Existe alguma situação em que você prefere um formulário ao outro?

Pessoalmente, tendo a preferir a primeira forma, apenas para evitar o uso de cachimbo. Acho que certamente os desenvolvedores finddevem ter feito as otimizações apropriadas. Estou correcto?

Responder1

A canalização segura de nomes de arquivos xargsrequer que você findsuporte a -print0opção e xargstenha a opção correspondente para lê-la ( --nullou -0). Caso contrário, nomes de arquivos com caracteres não imprimíveis ou barras invertidas, aspas ou espaços em branco no nome poderão causar um comportamento inesperado. Por outro lado, find -exec {} +está nofindEspecificação POSIX, por isso é portátil e é tão seguro quanto find -print0 | xargs -0e definitivamente mais seguro que find | xargs. eu recomendarianuncafazendo find | xargssem -print0.

Responder2

Você pode querer encadear ligações para descobrir (uma vez, quando você aprendeu, que é possível, o que pode ser hoje). É claro que isso só é possível enquanto você permanecer em busca. Depois de canalizar para xargs, ele estará fora do escopo.

Pequeno exemplo, dois arquivos a.lst e b.lst:

cat a.lst
fuddel.sh
fiddel.sh

cat b.lst
fuddel.sh

Não há truque aqui - simplesmente o fato de que ambos contêm "fuddel", mas apenas um contém "fiddel".

Suponha que não soubéssemos disso. Procuramos um arquivo que corresponda a 2 condições:

find -exec grep -q fuddel {} ";" -exec grep -q fiddel {} ";" -ls
192097    4 -rw-r--r--   1 stefan   stefan         20 Jun 27 17:05 ./a.lst

Bem, talvez você conheça a sintaxe do grep ou outro programa para passar ambas as strings como condição, mas esse não é o ponto. Todo programa que pode retornar verdadeiro ou falso, dado um arquivo como argumento, pode ser usado aqui - grep era apenas um exemplo popular.

E observe, você pode seguirencontrar -execcom outros comandos find, como-lsou-excluirou algo semelhante. Observe que delete não apenas faz rm (remove arquivos), mas também rmdir (remove diretórios).

Tal cadeia é lida como uma combinação AND de comandos, desde que não seja especificado de outra forma (ou seja, com uma -oropção (e parênteses (que precisam ser mascarados))).

Portanto, você não está saindo da cadeia de localização, o que é útil. Não vejo nenhuma vantagem em usar -xargs, já que você precisa ter cuidado ao passar os arquivos, o que é algo que find não precisa fazer - ele trata automaticamente a passagem de cada arquivo como um único argumento para você.

Se você acredita que precisa de alguma máscara para descobertas{} aparelho ortodôntico, fique à vontade para visitar minha pergunta que pede evidências. Minha afirmação é: você não.

Responder3

Se você usar o -exec ... ;formulário (lembrando de escapar do ponto e vírgula), estará executando o comando uma vez por nome de arquivo. Se você usar -print0 | xargs -0, você executa vários comandos por nome de arquivo. Definitivamente, você deve usar o -exec +formulário, que coloca vários arquivos em uma única linha de comando e é muito mais rápido quando um grande número de arquivos está envolvido.

Uma grande vantagem do uso xargsé a capacidade de executar vários comandos em paralelo usando o xargs -P. Em sistemas multi-core, isso pode proporcionar uma enorme economia de tempo.

Responder4

Em relação ao desempenho, pensei que -exec … +seria simplesmente melhor porque é uma única ferramenta que faz todo o trabalho, masuma parte da documentação do GNU findutildiz que -exec … +pode ser menos eficiente em alguns casos:

[encontrar com -exec … +]pode ser menos eficiente do que alguns usos de xargs; por exemplo, xargspermite que novas linhas de comando sejam criadas enquanto o comando anterior ainda está em execução e permite especificar vários comandos para serem executados em paralelo. No entanto, a find ... -exec ... +construção tem a vantagem de ampla portabilidade. GNU findutils não suportava ' -exec ... +' até a versão 4.2.12[Janeiro de 2005]; uma das razões para isso é que já tinha a -print0ação '' em qualquer caso.

Eu não tinha certeza do que isso significava, então perguntei no chat ondederobertoexplicou como:

findprovavelmente poderia continuar a procurar o próximo lote de arquivos enquanto o programa -exec … +está em execução, mas isso não acontece.
find … | xargs …faz, porque então o find é um processo diferente e continua em execução até que o buffer do pipe fique cheio

(Formatação feita por mim.)

Então é isso. Mas se o desempenho realmente importa, você terá que fazer um benchmarking realista ou até mesmo se perguntar se gostaria de usar o shell para tais casos.

Aqui neste site acho melhor aconselhar as pessoas a usarem o -exec … +formulário sempre que possível porque só porque é mais simples e pelos motivos mencionados nas outras respostas aqui (por exemplo, lidar com nomes de arquivos estranhos sem ter que pensar muito).

informação relacionada