{}
não tem absolutamente nenhum significado para bash
, então é passado sem modificações como um argumento para o comando executado, aqui find
.
Por outro lado, ;
tem um significado específico para bash
. É normalmente usado para separar comandos sequenciais quando eles estão na mesma linha de comando. Aqui, a barra invertida em \;
é usada precisamente para impedir que o ponto-e-vírgula seja interpretado como um separador de comando por bash
e, em seguida, permitir que ele seja passado como um parâmetro para o comando subjacente, find
. A citação do ponto-e-vírgula, ou seja, ";"
ou ';'
, poderia ter sido uma maneira alternativa de não ser processada.
O comando:
find ./ -size 0 -exec rm -i {} \;
significa: encontre no diretório atual (note que /
é inútil aqui, .
não pode ser senão um diretório) qualquer coisa que tenha um tamanho de 0 e para cada objeto encontrado, execute o comando rm -i name
, ou seja, solicitar interativamente para cada arquivo, se você quiser removê-lo. {}
é substituído por cada nome de arquivo encontrado no comando executado. Uma característica interessante é que esse nome de arquivo é estritamente um único argumento, qualquer que seja o nome do arquivo (mesmo contendo espaços incorporados, tabulações, alimentações de linha e quaisquer caracteres). Este não seria o caso de xargs
, a menos que hacks não portáteis sejam usados. O% final ;
está lá para terminar a cláusula -exec
. A razão pela qual seu fim precisa ser delimitado é que outras cláusulas find
podem seguir o -exec
, embora isso raramente seja feito.
Um problema com esse comando é que ele não ignorará arquivos não-simples, portanto, pode solicitar que o usuário exclua soquetes, dispositivos de bloco e de caractere, canais e diretórios. Ele sempre falhará com este último, mesmo se você responder sim.
Outro problema, embora não muito crítico aqui, é que rm
será chamado para cada arquivo com tamanho zero. Se você substituir o -exec
de /;
a +
, find
otimizará a criação do subprocesso chamando apenas rm
o número mínimo possível de vezes, muitas vezes apenas uma vez.
Aqui está como eu modificaria esse comando:
find . -type f -size 0 -exec rm -i {} +