Bul (1) 'in -exec seçeneğini (kıvırcık ayraçlar ve artı işareti) anlama


17

Aşağıdaki komutu kullanarak birisi, sonlanan süslü parantez ({}) ve artı işaretinin (+) amacının tam olarak ne olduğunu açıklayabilir mi?

Ve komuttan çıkarılırlarsa komut nasıl farklı çalışır?

find . -type d -exec chmod 775 {} +

Yanıtlar:


19

Kıvırcık parantezlerin yerine findkomutun sonuçları gelir ve chmodher birinin üzerinde çalıştırılır. +Markaları findmümkün olduğunca az komutlar olarak çalıştırmayı denediğinizde (yani chmod 775 file1 file2 file3karşıt olarak chmod 755 file1, chmod 755 file2, chmod 755 file3). Bunlar olmadan komut sadece bir hata verir. Bütün bunlar şu şekilde açıklanmaktadır man find:

-exec command ;

      Yürütme komutu ; 0 durumu döndürülürse true. Aşağıdaki tüm bağımsız finddeğişkenler, ' ;' ifadesinden oluşan bir bağımsız değişkenle karşılaşılana kadar komuta bağımsız değişken olarak alınır . ' {}' Dizesinin yerine, bazı sürümlerinde olduğu gibi, yalnızca yalnız olduğu bağımsız değişkenlerde değil, komutun bağımsız değişkenlerinde gerçekleştiği her yerde işlenen geçerli dosya adı kullanılır find. ...

-exec command {} +

      -execEylemin bu değişkeni , seçilen dosyalarda belirtilen komutu çalıştırır, ancak komut satırı, seçilen her dosya adı sonuna eklenerek oluşturulur; komutun toplam çağrı sayısı, eşleşen dosya sayısından çok daha az olacaktır. ...


12

Terdon'un cevabına ek olarak,

  • “Açıkçası” -exec …, noktalı virgül ( ;) veya artı işaretiyle ( +) sonlandırılmalıdır . O kullanılacak ise noktalı virgül kabuk (veya en azından, her şimdiye kadar kullandığım kabuk) özel bir karakter, bu nedenle, bir parçası olarak findkomuta , o kaçan veya tırnak içinde olmalıdır ( \;, ";"veya ';').
  • İle -exec … ;, {}dize, komuta kez herhangi bir sayıda görünebilir sıfır dahil her pozisyonda, ya da iki veya daha fazla.  Bkz bu yapmak istediğiniz nedenlerine ilişkin bir örnek için -execkullanmadan {}.   İki veya daha fazla görünüşleri olması yararlıdır esas, çünkü (en azından) bazı sürümleri find, {}tek başına bir kelime olmak gerekmez; başında veya sonunda başka karakterler olabilir; Örneğin,

    find . -type f -exec mv {} {}.bak ";"
    

    İle -exec … +, {}dize , öğesinden önceki son bağımsız değişken olarak görünmelidir +. Gibi bir komut

    find . -name "*.bak" -exec mv {} backup_folder +
    

    gizemli find: missing argument to ‘-exec’hata iletisiyle sonuçlanır .

    • cpVe mvkomutlarına özgü bir çözüm şu şekildedir:

      find . -name "*.bak" -exec mv -t backup_folder {} +
      

      veya

      find . -name "*.bak" -exec mv --target-directory=backup_folder {} +
      

    Tek {}başına bir kelime olmalı; başında veya sonunda başka karakterler olamaz. Ve (en azından) bazı sürümlerinde findbirden fazla sürümünüz olmayabilir {}.

  • Bir akıl sağlığı notu:

    bulmak. -name "* .sh" -tip f -ekneklenebilir -exec {} burada isteğe bağlı argümanlar ";"

    komut dosyalarınızın her birini çalıştırmak için. Fakat

    bulmak. -name "* .sh" -tip f -ekneklenebilir -exec {} +

    ishal birini parametre olarak tüm diğerlerinin adlarıyla komut. Bu söylemeye benzer

    ./*.sh
    

    bir kabuk komutu olarak, bunun dışında find, sonuçlarının sıralandığını garanti etmez, bu nedenle, çalıştırdığınız gibi çalışacağınız aaa.sh (alfabetik olarak ilk *.shdosyanız) garanti edilmez ./*.sh.

  • Bunun findyeni başlayanlar için tam olarak anlaşılamayacak bir yönü , komut satırının etkili bir şekilde gizli bir dilde yürütülebilir bir deyim olmasıdır . Örneğin,

    find . -name "*.sh" -type f -executable -print
    

    anlamına geliyor

    for each file
        if the file’s name matches `*.sh` (i.e., if it ends with `.sh`)
        then
            if it is a plain file (i.e., not a directory)
            then
                if it is executable (i.e., the appropriate `---x--x--x` bit is set)
                then
                    print the file’s name
                end if
            end if
        end if
    end loop
    

    ya da sadece,

    for each file
        if the file’s name matches `*.sh`  AND  it is a plain file  AND  it is executable
        then
            print the file’s name
        end if
    end loop
    

    Bazı -anahtar kelimeler yürütülebilir bir eylem ve bir test ikisi de. Özellikle, bu doğrudur -exec … ;; Örneğin,

    find . -type f -exec grep -q cat {} ";" -print
    

    Çevirir

    her dosya için
        düz bir dosyaysa (yani, bir dizin değil)
        sonra
            grep -q kedi dosya adını yürüt
            işlem başarılı olursa (yani, durum 0'dan çıkarsa)
            sonra
                dosyanın adını yazdır
            eğer biterse
        eğer biterse
    bitiş döngüsü

    cat” dizesini içeren tüm dosyaların adlarını basacaktır . Ve bu grepkendi başına yapabilen bir şey olsa da -l((küçük harfli L) seçeneğiyle), findbelirli bir dize içeren ve belirli bir boyuta sahip VE belirli bir sahipe ait dosyaları bulmak için kullanmak yararlı olabilir. AND belirli bir zaman aralığında değiştirildi,….

    Ancak, bu işe yaramaz -exec … +. Yana -exec … +birden fazla dosya için yürütür tek bir komut, bir iç mantıksal koşul olarak kullanmak için bir anlam ifade etmiyor for each file …döngü.

  • Yukarıdakilerin kapak tarafı, findgeçersiz argümanlar vermedikçe veya okuyamadığı bir dizinle karşılaşmadığı sürece genellikle 0 çıkış durumundan çıkar. Yürüttüğünüz bir program başarısız olsa bile (sıfır olmayan çıkış durumundan çıkar), find0 çıkış durumuyla çıkar.  hariç  Birlikte çalıştırması bir program varsa-exec … +(sıfır olmayan bir çıkış durumu ile çıkar) başarısız, findçıkar sıfır olmayan bir çıkış durumuna sahip.

Bir milyon versiyonlarına ek olarak find(1) ve hangi test findaslında sistemlerin bir çift yapar, Açık Grubu Baz Özellikleri Sayı 7, 2013 Sürümü bilgilerin bir kısmını temin neyifind yapılması, yapılmaması gerektiğine .


3
Örnek ... -exec mv {} {}.bak ...kullanımınızın tüm finduygulamalarda beklendiği gibi çalışacağının garantisi olmadığına dikkat edin . POSIX standart durumlarının {}her zaman tanınabilmesi için tek başına görünmeleri gerekir, aksi takdirde davranış karakterleri değiştirmeden tutmak veya yol adıyla değiştirmek serbesttir. Önceki durumda, tüm komutunuz esasen son bulunan dosya hariç tüm dosyaları silecektir ...
jlliagre
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.