'find -delete' Apagado Tudo

7

Eu não estou muito familiarizado com find e consegui excluir uma tonelada de arquivos por acidente. Eu queria saber se alguém mais experiente poderia explicar onde eu errei.

Eu queria limpar todos os arquivos .DS_Store e ._.DS_Store que o Finder do meu MacBook exibia em todo o meu compartilhamento de samba do Raspbian.

  • Eu tenho um disco rígido conectado ao meu pi de framboesa, com alguns links simbólicos na minha pasta pessoal para o ponto de montagem, daí o -L .
  • Algumas das pastas são de propriedade de usuários do sistema (por exemplo, apache). sudo .

Corri o seguinte para garantir que find segmentasse os arquivos certos:

hydraxan@raspberry:~ $ sudo find -L . -maxdepth 255 -name \*DS_Store\*
./.DS_Store
./Downloads/USBHDD1/._.DS_Store
./Downloads/USBHDD1/.DS_Store
./Downloads/USBHDD1/backups/ALAC/._.DS_Store
./Downloads/USBHDD1/backups/ALAC/Jeff Van Dyck - Assault Android Cactus OST/._.DS_Store
./Downloads/USBHDD1/backups/ALAC/Jeff Van Dyck - Assault Android Cactus OST/.DS_Store
./Downloads/USBHDD1/backups/ALAC/.DS_Store
./Downloads/USBHDD1/backups/._.DS_Store
./Downloads/USBHDD1/backups/.DS_Store
./Downloads/USBHDD1/backups/OriginalMusic/._.DS_Store
./Downloads/USBHDD1/backups/OriginalMusic/.DS_Store
./Downloads/USBHDD1/backups/OriginalMusic/FLAC/.DS_Store
./Downloads/USBHDD1/backups/Storage/._.DS_Store
./Downloads/USBHDD1/backups/Storage/.DS_Store
./Downloads/OriginalMusic/._.DS_Store
./Downloads/OriginalMusic/.DS_Store
./Downloads/OriginalMusic/FLAC/.DS_Store
./Downloads/ALAC/._.DS_Store
./Downloads/ALAC/Jeff Van Dyck - Assault Android Cactus OST/._.DS_Store
./Downloads/ALAC/Jeff Van Dyck - Assault Android Cactus OST/.DS_Store
./Downloads/ALAC/.DS_Store

Tudo parece bom!

Em seguida, adicionei o sinal -delete para fazer com que find removesse os arquivos encontrados:

hydraxan@raspberry:~ $ sudo find -L . -maxdepth 255 -delete -name \*DS_Store\*
find: cannot delete './Documents': Not a directory
find: cannot delete './Pictures': Not a directory
find: cannot delete './Music': Not a directory

Depois que percebi que estava tentando excluir meus links simbólicos por algum motivo, digitei Ctrl+C e salvei metade dos dados.

Documentos, fotos e músicas são torradas. Provavelmente estava trabalhando na minha gigantesca pasta Downloads que eu coloquei em quase tudo.

Por que find excluiu todos esses arquivos? Coloquei -delete no lugar errado?

    
por Hydraxan14 13.01.2017 / 02:13

2 respostas

12

Sua resposta está em find manpage.

A opção de exclusão é processada antes do seu filtro de nomes.

       -delete
          Delete files; true if removal succeeded.  If the removal failed,
          an  error message is issued.  If -delete fails, find's exit sta‐
          tus will be nonzero (when it eventually exits).  Use of  -delete
          automatically turns on the -depth option.

          Warnings:  Don't  forget that the find command line is evaluated
          as an expression, so putting -delete first will make find try to
          delete everything below the starting points you specified.  When
          testing a find command line that you later intend  to  use  with
          -delete,  you should explicitly specify -depth in order to avoid
          later surprises.  Because -delete  implies  -depth,  you  cannot
          usefully use -prune and -delete together.

Você poderia ter movido a opção de exclusão como a última do seu comando

Alternativamente, você poderia ter usado algo como

find /path -name "*pattern*" | xargs rm -f

ou

find /path -name "*pattern*" -exec rm -f {} \;
    
por 13.01.2017 / 02:22
0

O princípio básico da linha de comando de find é “se condição e condição e… então ação”. Note que a ação vem por último - é bem diferente do formato de chamar um comando que é “objeto de objeto de ação…”.

Por exemplo, find . -name \*DS_Store\* -delete significa "se o nome corresponder a *DS_Store* e, em seguida, excluir". Se você inverter a condição e a ação, a ação -delete não terá nenhuma condição por trás disso, por isso é aplicada incondicionalmente.

A razão pela qual find . -delete -name \*DS_Store\* não é um erro de sintaxe é que ações também são condições. A ação -delete é uma condição verdadeira se for bem-sucedida e é falsa se falhar (por exemplo, devido à falta de permissões). Por exemplo, find . -name somethingorother -delete -print imprime os nomes dos arquivos que são excluídos com sucesso.

O motivo pelo qual find -name \*DS_Store\* não é um erro de sintaxe é que, se não houver ação, haverá uma ação -print implícita. Foi concebido desta forma porque a impressão é uma escolha muito comum de ação.

(Observe que, embora minha resposta não contenha uma mentira descarada, simplifica algumas coisas. Existem recursos de find que as explicações em minha resposta não cobrem, em particular a ! e -o lógica operadores.)

    
por 13.01.2017 / 21:15

Tags