A sintaxe é:
find ... -exec cmd {} +
find
encontrará vários arquivos com base nos critérios em ...
e executará cmd
com essa lista de caminhos de arquivos como argumentos, o maior número possível sem ultrapassar o limite do tamanho dos argumentos para um comando.
Se necessário, pode dividir a lista de arquivos e chamar cmd
várias vezes. Por exemplo, pode acabar chamando:
cmd ./file1 ./file2 ... ./file3000
cmd ./file3001 ./file3002 ... ./file4321
Uma limitação é que {}
tem que ser o último. Você não pode, por exemplo, escrever:
find ... -exec cmd {} other args +
como você poderia com ';'
em vez de '+'
.
Você pode escrever:
find ... -exec echo foo {} +
mas não:
find ... -exec echo {} foo +
Portanto, se você precisar adicionar alguns argumentos extras a cmd
após a lista de arquivos, precisará recorrer a chamar um shell. (Outras razões pelas quais você precisaria chamar um shell seriam sempre que precisar usar um recurso de shell como redirecionamentos, pipes, algumas expansões de strings ....)
Em sh -c 'inline-script' x a b c
, para inline-script
, $0
é x
, $1
é a
, $2
é b
... então, "$@"
é a lista desses 3 argumentos: a, b e c. Então, em:
find ... -exec sh -c 'cmd "$@" other arg' find-sh {} +
Para o script in-line , $0
(que é usado por exemplo ao exibir mensagens de erro) está definido como find-sh
e "$@"
é a lista de arquivos (que find
expande {}
para).
Usando o exec
especial embutido no shell:
find ... -exec sh -c 'exec cmd "$@" other arg' find-sh {} +
Dizemos ao shell para não bifurcar um processo extra para executar cmd
, mas em vez disso executá-lo no mesmo processo (substituindo o processo do shell em execução por esse comando). Alguns shells como bash
, zsh
e algumas implementações de ksh
fazem isso implicitamente para o último comando em um script.