A sintaxe é:
find ... -exec cmd {} +
find
encontrará vários arquivos com base nos critérios ...
e será executado cmd
com essa lista de caminhos de arquivos como argumentos, o maior número possível, sem ultrapassar o limite no tamanho dos argumentos de um comando.
Se necessário, pode dividir a lista de arquivos e ligar cmd
várias vezes. Por exemplo, pode acabar chamando:
cmd ./file1 ./file2 ... ./file3000
cmd ./file3001 ./file3002 ... ./file4321
Uma limitação disso é que {}
deve ser a última. 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 para cmd
depois da lista de arquivos, precisará recorrer à chamada de shell. (Outras razões pelas quais você precisaria chamar um shell seria sempre que precisar usar um recurso de shell, como redirecionamentos, canais, algumas expansões de cadeia ...)
Em sh -c 'inline-script' x a b c
, para o inline-script
, $0
é x
, $1
é a
, $2
é b
... assim "$@"
como a lista desses 3 argumentos: a, bec. Então em:
find ... -exec sh -c 'cmd "$@" other arg' find-sh {} +
Para o script embutido , $0
(que é usado, por exemplo, ao exibir mensagens de erro), é definido como find-sh
e "$@"
é a lista de arquivos (o que se find
expande {}
).
Usando o exec
builtin especial do 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 para executá-lo no mesmo processo (substituindo o processo do shell em execução por esse comando). Alguns escudos como bash
, zsh
e algumas implementações de ksh
fazer isso de forma implícita para o último comando em um script.
-exec sh -c '(cmd1; cmd2;)' find-sh {} +
?find-sh {}
existem argumentos para o comando sh -c '...', certo?find
vai chamar/bin/sh
com como argumentos("sh", "-c", "...", "find-sh", "./file1", "./file2"...). And inside
..., that maps (the shells maps that) to
$ 0` ser"find-sh"
, e os parâmetros de posição ($1
,$2
... o que você poderia dizer que são os argumentos para o script embutido ), sendo./file1
,./file2
.