Eu entendo que eles -exec
podem 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 find
devem ter feito as otimizações apropriadas. Estou correcto?
Responder1
A canalização segura de nomes de arquivos xargs
requer que você find
suporte a -print0
opção e xargs
tenha a opção correspondente para lê-la ( --null
ou -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á nofind
Especificação POSIX, por isso é portátil e é tão seguro quanto find -print0 | xargs -0
e definitivamente mais seguro que find | xargs
. eu recomendarianuncafazendo find | xargs
sem -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 -or
opçã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 dexargs
; por exemplo,xargs
permite 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, afind ... -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-print0
ação '' em qualquer caso.
Eu não tinha certeza do que isso significava, então perguntei no chat ondederobertoexplicou como:
find
provavelmente 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).