Por favor, considere o seguinte comando:
find . -type f -name '*.*' -exec mv '{}' '{}_foo' \;
Como find
evitar loops infinitos neste caso?
Por um lado, acredito saber que find não funciona como os shell globs, ou seja, não busca uma lista de todos os *.jpg
arquivos, armazena essa lista internamente e depois processa as entradas da lista . Em vez disso, ele faz com que os arquivos sejam processados "incrementalmente" a partir do sistema operacional subjacente e processa cada um deles assim que souber (vamos ignorar uma certa quantidade de buffer que pode ocorrer, pois isso é irrelevante para a questão). Afinal, pelo que entendi, essa é a principal vantagem do find
over globs em diretórios que contêm muitos arquivos.
Se isso for verdade, gostaria de entender como find evita loops sem fim. No exemplo acima, 1.jpg
seria renomeado para 1.jpg_foo
. De discussões no StackOverflow e em outros lugares, eu sei que renomear pode resultar no arquivo (nome) ocupando um slot diferente na lista de arquivos do diretório, então é provável que encontre esse arquivo uma segunda vez, renomeie-o novamente (para 1.jpg_foo_foo
), e assim sobre.
Obviamente, isso não acontece.
Dentro de um único diretório, pode ser tão simples quanto ler toda a lista de arquivos antes de processá-la (e
strace
faz parecer que é isso que acontece):(saída abreviada para facilitar a leitura)
Em geral, porém,
find
não impede nenhum loop. Se você mover arquivos para um subdiretório, isso acontecerá várias vezes:Isso resulta em
sub/sub/sub/sub/file_foo_foo_foo_foo
e tais coisas. (-depth
pode ajudar neste caso).É melhor evitar possíveis confrontos em primeiro lugar, em vez de confiar cegamente no
find
emprego de alguma magia que simplesmente não existe. Sua pergunta antes da edição foi uma boa solução, pois simplesmente não correspondia ao arquivo já renomeado.Mesmo nos casos em que não seja estritamente necessário, é bom deixar claro que os arquivos não podem e não devem ser processados duas vezes. Estamos renomeando
jpg
arquivos aqui e nãofoo
arquivos.Além disso, mesmo que
find
uma única chamada impeça o processamento de arquivos duas vezes, sempre há o risco de o script como um todo ser executado novamente e o find será executado uma segunda vez, portanto, você precisará de salvaguardas de qualquer maneira.