'Find -delete' neden bir dizindeki tüm dosyaları özyinelemeli olarak siler


15

Yani aşağıdaki unix davranışı bana pahalıya mal oldu:

> touch foo
> touch bar
> ls  
bar  foo
> find . -name '*oo' -delete
> ls
bar
> touch baz
> ls
bar  baz
> find . -delete -name '*ar'
> ls
> #WHAAAT?

Bu nasıl bir anlam ifade ediyor?


2
Bu soru ilişkilidir, gelecekteki okuyucular için ilginç olabilir. unix.stackexchange.com/questions/101282/…
Bernhard

Yanıtlar:


14

Bulma komut satırı, ifade oluşturmak için birleştirilen farklı seçeneklerden yapılır.

findSeçenek -deletebir eylemdir.
Bu, şimdiye kadar eşleşen her dosya için yürütüldüğü anlamına gelir.
Yollardan sonra ilk seçenek olarak, tüm dosyalar eşleşir ... ayy!

Tehlikelidir - ancak kılavuz sayfanın en azından büyük bir uyarısı vardır :

Gönderen man find:

ACTIONS
    -delete
           Delete  files; true if removal succeeded.  If the removal failed, an
           error message is issued.  If -delete fails, find's exit status  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.


Aşağıdakilerden itibaren man find:

EXPRESSIONS
    The expression is made up of options (which affect overall operation rather
    than  the  processing  of  a  specific file, and always return true), tests
    (which return a true or false value), and actions (which have side  effects
    and  return  a  true  or false value), all separated by operators.  -and is
    assumed where the operator is omitted.

    If the expression contains no actions other than  -prune,  -print  is  per‐
    formed on all files for which the expression is true.


Bir findkomutun ne yapacağını denerken :

Bir komutun nasıl olduğunu görmek için

find . -name '*ar' -delete

silerseniz, önce eylemi -deletedaha zararsız bir eylemle değiştirebilirsiniz - -flsveya -print:

find . -name '*ar' -print

Bu işlemden hangi dosyaların etkilendiğini yazdıracaktır.
Bu örnekte, -print dışarıda bırakılabilir. En belirgin örtülü eklenir yani bu durumda, hiç aksiyon yok: -print. (Yukarıda belirtilen "İFADELER" bölümünün ikinci paragrafına bakınız)


Ben sadece manuel ilk Okumadığım için bir aptal olduğunu tahmin .. Ama sadece eklemek kadar basit görünüyordu -deletebayrağı :-) Ama şimdiye kadar yapmak için bir neden kimse var mı find . -deleteziyade rm -rf .? Yoksa bu sadece findargümanlarını ayrıştırma ve işleme biçimi midir?
mszep

1
Oh, sözdiziminin çok tehlikeli olduğuna tamamen katılıyorum - ancak kaçınılması zor, çünkü bu, çok güçlü olan bulgunun çizgi satırı ifadesi sözdiziminin özel bir örneğidir. " Güçlü bir testere " de olduğu gibi güçlü .
Volker Siegel

alıntılanan kılavuz sayfası warning: use -depth when testing stuff you later want to -deletepratikte yan örneğinde yapmadığınızı söylemiyor mu?
pqnet

Oh, doğru - sorun başlık - Ben bir -nseçenek gibi -delete yerine baskı kullanımını göstermek istedim ; İlk komutun hiç bir pratik kullanımı olmamalıdır elbette; Gidip değiştireceğim.
Volker Siegel

9

In findargüman emri, çok önemli.

Bağımsız değişkenler seçenekler, testler ve eylemler olabilir. Genellikle önce seçenekleri, ardından testleri, ardından eylemleri kullanmalısınız.

Bazen findsizi olası bir kötü düzen hakkında uyarır (örneğin, -maxdepthdiğer argümanlardan sonra kullandığınızda ), ancak diğerleri öyle görünmüyor.

Ne find . -delete -name '*ar'yapar:

  1. Geçerli dizinde dosyaları ve dizinleri bulur.
  2. Buldukları gibi TÜM onları siler!
  3. Sonra '* ar' olarak adlandırılıp adlandırılmadığını görür (bu bölümün artık bir etkisi yoktur).

Muhtemelen yapmak istediğiniz şey:

find -name '*ar' -delete

Bu, her dosya için eşleşip eşleşmediğini görecek '*ar've yalnızca koşulu karşıladığında dosyayı silecektir.

Çok geç öğrendiysen üzgünüm.

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.