Elimina file e directory con i loro nomi. Nessun file o directory con questo nome


32

Devo eliminare tutti i dati compilati:

  • directory chiamate build,
  • directory chiamate obj,
  • * .so file.

Ho scritto un comando

find \( -name build -o -name obj -o -name *.so \) -exec rm -rf {} \;

che attraversa ricorsivamente tutte le directory ed elimina tutto ciò di cui ho bisogno.

Perché ho un tale output alla fine? Forse dovrei scrivere un comando diverso.

find: `./3/obj': No such file or directory
find: `./3/build': No such file or directory
find: `./1/obj': No such file or directory
find: `./1/build': No such file or directory
find: `./2/obj': No such file or directory
find: `./2/build': No such file or directory

su quale sistema sei? dovresti sempre usare in findquesto modo find /search_directory optionsomettere la directory di ricerca non è una buona idea
Kiwy,

L'eliminazione automatica come questa è una cattiva idea. Potresti avere una sceneggiatura che ti dia dei candidati, che dovresti quindi guardare per assicurarti di non eliminare nulla di importante o necessario dal sistema. Non sei esplicito dove lo stai eseguendo. Se lo stai facendo solo in uno spazio utente, suppongo che non possa fare molto male, ma dovresti assicurarti di non farlo accidentalmente nell'area di sistema. Sicuramente vuoi eseguire uno script come utente.
Faheem Mitha,

@ Kiwy, @ FaheemMitha, il comando verrà utilizzato solo nel progetto diretto; non farà alcun danno lì.
Maksim Dmitriev,

Risposte:


54

Usa -prunenelle directory che eliminerai comunque per dire di findnon preoccuparti di cercare i file in esse contenuti:

find . \( -name build -o -name obj -o -name '*.so' \) -prune -exec rm -rf {} +

Si noti inoltre che *.sodeve essere citato in quanto altrimenti potrebbe essere espanso dalla shell all'elenco dei .sofile nella directory corrente.

L'equivalente del tuo GNU- -regextipo uno sarebbe:

find . \( -name build -o -name obj -o -name '*?.so' \) -prune -exec rm -rf {} +

Nota che se stai per usare la sintassi specifica GNU, potresti anche usare -deleteinvece di -exec rm -rf {} +. Con -delete, GNU findsi accende -depthautomaticamente. Non esegue comandi esterni in questo modo, è più efficiente, ed è anche più sicuro in quanto rimuove la condizione di competizione in cui qualcuno potrebbe essere in grado di farti rimuovere i file sbagliati cambiando una directory in un link simbolico nel tempo findtrova un file e lo rmrimuove (vedere info -f find -n 'Security Considerations for find'per i dettagli).

find . -regextype posix-egrep -regex '.*/((obj|build)(/.*)?|.+\.so)' -delete

-deletegestisce anche meglio cose come gli spazi
Izkata,

@Izkata, non meglio di quello -exec rm -rf {} +che non ha alcun problema con quelli.
Stéphane Chazelas,

@StephaneChazelas - Sono confuso {}- dovrebbero essere citati o no? Sembra funzionare senza virgolette, ma GNU Findutils Manual usa '{}'ad esempio. Potresti chiarire, per favore?
Grebneke,

1
@grebneke, penso che ci sia un post da qualche parte in cui affermazioni potrebbero essere necessarie citazioni in versioni molto vecchie di csh, ma non ho mai potuto verificare tale affermazione. Non sono necessari in nessuna shell moderna che io conosca. Non sono assolutamente richiesti da POSIX. Gli esempi POSIX non li usano.
Stéphane Chazelas,

3
E -deletenon può essere utilizzato con le directory.
St0rM,

8

Immagino che il motivo sia che findelimina prima l'albero delle directory e cerca di controllare il contenuto della directory che ovviamente non è il miglior ordine possibile. Puoi forzare finda controllare prima i contenuti:

find . -depth ...

Dovresti considerare l'utilizzo -deleteper i file e -exec rmdirper le directory.


0

La mia soluzione.

find . -regextype posix-egrep -regex ".*/(obj|build|.+\.so)" -prune -exec rm -rf {} +

+ vs \; nel comando -exec


Questo non funzionerà sempre, solo se non esiste alcun limite tra le esecuzioni all'interno di una directory eliminata.
Gilles 'SO- smetti di essere malvagio' il

@Gilles, cosa significa "confine tra esecuzioni"?
Maksim Dmitriev il

1
-exec … {} +esegue il comando per più file alla volta, quanti ne rientrano nella riga di comando. Se ci sono troppi file (o più precisamente se la lunghezza totale dei percorsi è troppo lunga), findeseguirà più istanze di rm, e quindi potrebbe finire per rimuovere una directory che sta attraversando. È meno probabile con +che con ;, ma +non risolve il problema.
Gilles 'SO- smetti di essere malvagio' il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.