find -delete boş olmayan dizinleri silmez


32

Komuta

$ find ~ -name .DS_Store -ls -delete

Mac OS X’de çalışır, ancak

$ find ~ -name __pycache__ -type d -ls -delete

yok - dizinler bulundu ancak silinmedi.

Niye ya?

PS. Yapabileceğimi biliyorum

$ find ~ -name __pycache__ -type d -ls -exec rm -rv {} +

soru neden find -delete yok değil çalışır.

Yanıtlar:


36

find'ın -deletebayrağı rmdirdizinleri silerken olduğu gibi çalışır . Dizin ulaştığında boş değilse silinemez.

İlk önce dizini boşaltmanız gerekir. Belirttiğinden beri -type d, findbunu senin için yapmaz.

Bunu iki geçiş yaparak çözebilirsiniz: önce adlı dizindeki her şeyi silin __pycache__, sonra adlı dizilerin hepsini silin __pycache__:

find ~ -path '*/__pycache__/*' -delete
find ~ -type d -name '__pycache__' -empty -delete

Biraz daha az sıkı kontrol edilir, ancak tek bir satırda:

find ~ -path '*/__pycache__*' -delete

Bu, evinizin içinde __pycache__yolunun bir parçası olan herhangi bir şeyi siler .


4.4.2'de bu son komutun güvende olması find ~ -path '*/__pycache__*' -deleteveya muhtemelen find ~ -path '*/__pycache__/*' -o -name __pycache__ -deletegüvende olması gerekir.
na1101

3
@ naught101 olması gerektiği find ~ \( -path '*/__pycache__/*' -o -name __pycache__ \) -deleteşekilde ve fazla önceliğe sahiptir ya da .
Stéphane Chazelas

6

Bunun birkaç olası nedeni var.

1) Yalnızca dizinleri ( -type d) silmesini söylediniz ve bu dizinlerin içinde hala dosyalar var.

2) Dizinleriniz sadece başka dizinler içermektedir, dolayısıyla -type diçerik sorunuyla ilgilenecektir. Ancak, büyük ölçüde FreeBSD'ye dayanan OS-X kullanıyorsunuz ve FreeBSD findvarsayılan olarak dizini içeriğinden önce işleyecektir.
Bununla birlikte, -depthbu sorunu çözme seçeneği find, dizini içeriğinden sonra işlemeyi söyleyerek çözülür .

find ~ -name __pycache__ -type d -ls -delete -depth

Bu sorun linux'ta mevcut değildir, çünkü -deleteseçenek dolaylı olarak etkindir -depth.

 

FreeBSD man 1 find:

 -depth  Always true; same as the non-portable -d option. Cause find to
   perform a depth-first traversal, i.e., directories are visited in
   post-order and all entries in a directory will be acted on before
   the directory itself. By default, find visits directories in
   pre-order, i.e., before their contents. Note, the default is not
   a breadth-first traversal.

GNU man 1 find:

 -depth Process each directory's contents before the directory itself. The -delete
        action also implies -depth.

2
Evet ama FreeBSD bulmak (1) diyor -delete“... Derinlik öncelikli geçişi işleme bu seçenek ima edilmektedir.”, Ve GNU bulmak (1) diyor “... -sil ima -depth , ...”, bu yüzden olmamalı -depthKomuta eklemek için gerekli olması gerekir .
G-Man

1
GNU findman sayfasından: " Kargaşayı önlemek için, başlangıç ​​noktası listesinden sonraki komut satırında, ilk test, konumlandırma seçeneği veya eylemden hemen önce genel seçenekler belirtilmelidir. Başka bir yerde genel bir seçenek belirtirseniz, Bunun kafa karıştırıcı olabileceğini açıklayan bir uyarı mesajı yayınlayın. " Şimdi, verilen komuttan -deletesonra bir "global seçenek" ~. Ayrıca ekleyip eklemeyeceğinizin hiçbir önemi olmadığını da farkettim -depth. Boş olmayan dizinler silinmemiş kalır (ancak bu muhtemelen kullandığım için -maxdepthde geçerlidir)
David Tonhofer 17:17
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.