binlerce dosyada chmod özyinelemeli izin


16

Bu, 'chmoding' hakkında özyineli olarak daha genel bir sorudur.

Ben bir noktada izinleri birkaç yüz bin dosyaları olan bir klasörde özyineli olarak değiştirmek için gereken bu komut dosyası var. Bu klasöre her gün yeni dosyalar eklenir, ancak zaten orada olan izinler önceden ayarlanmıştır ve değişmezler.

Benim sorum ... aradığımda

chmod 775. -R

önceden doğru izinleri ayarlanmış dosyalar için veya yalnızca doğru izinleri olmayan yeni dosyalar için izin ayarlamaya çalışıyor mu?

'Yeni' dosyalar sadece birkaç bin olsa da izinleri oldukça hızlı bir şekilde yapsa da, komut dosyasında bu komutu geçmesi her zaman çok zaman alıyor.

Chmod için man sayfasına baktım, ancak bu davada bir şeyden bahsetmiyor gibi görünüyor.

Eğer chmod önceden izinleri kontrol etmezse, 'find' ile 'chmod' u birleştirmeye bakmaya başlamalı mıyım?


3
İzinleri kontrol etmek ve doğru olmadıklarında doğrudan doğru değere ayarlamak yerine değiştirmek gerçekten yavaş mı acaba?
lgeorget

1
eğer birisi bunun üzerine tökezliyorsa ve find + chmod komutunu istiyorsa, işte burada: bul. ! -perm 775 -print0 | xargs -0 -I {} chmod 775 {}
Titi Dumi

@lgeorget, bu nedenle find | chmod? her şeyi chmod etmekten daha fazlası. (üzgünüm, yorumunuzdan anlamadım). şerefe
Titi Dumi

Benim düşünceme göre, muhtemelen iki işlemden geçmesi ve birincinin çıktısını ikinciye yönlendirmesi gerektiği için daha yavaş ama emin değilim. Bu önemli olmayan izinleri ayarlamak için gereken süreye bağlıdır, çünkü inode'da değiştirmek için sadece 3 bayt olduklarından.
lgeorget

1
@depquid Buradaki ana performans sorunu, verileri disk önbelleğine okumaktır. İlk çalıştırmadan sonra her şey disk önbelleğinde (çok az bellek olmadığı sürece), böylece gerçek durumda darboğaz olmayan bir şeyin performansını test ediyorsunuz.
Hauke ​​Laging

Yanıtlar:


9

chmodzaten istediklerinize ayarlanmış olan dosyaların izinlerini değiştirebilir veya değiştirmeyebilir, ancak değiştirilmediyse geçerli izinlerinin ne olduğunu görmek için dosyalarınızı kontrol etmeniz gerekir [0]. Yüz binlerce dosyayla, her iki şekilde de önemli olacağını düşünmüyorum; zaman büyük olasılıkla stather dosyadaki araçlar tarafından harcanmaktadır .

findSon çalıştırmadan daha yeni dosyaları veya gereken dosyaları kontrol etmek için kullanmayı deneyebilirsinizchmod , ancak çok fazla hız iyileştirmesi alacağınızı düşünmüyorum.

Komut dosyanız için mümkünse, yeni dosyaları önce "bekletme" alanı olarak ayrı bir dizine yerleştirebilirsiniz. Sonra bu chmod(sadece yeni dosyaları olan) dizin mvve geri kalanı ile onları yapabilirsiniz. Bu çok daha hızlı olmalı, ancak maalesef her uygulama için işe yaramayacak.

[0] Herhangi bir değişikliğe ihtiyaç duymayan dosyaların iznini ayarlamaya çalışsa bile, temeldeki dosya sistemi istekle ilgili hiçbir şey yapmaz, çünkü gereksizdir.


Bunun için teşekkürler. Bulmaya çalışacağım | chmod sürümü ve daha hızlı bir şey yapıp yapmadığını görün. Değilse, önerdiğiniz gibi bir 'tutma' klasörü uygulamak için komut dosyasını değiştirmeye çalışacağım.
Titi Dumi

Hız artışı almamanızın nedeni, inode'un hem ctime hem de erişim hakları için okunması gerektiğidir.
Hauke ​​Laging

10

find / chmod optimizasyonu

Her ikisi de findve chmodokumak zorunda

  1. tüm dizin girişleri
  2. tüm bu girdilerin düğümleri

Muhtemelen önce tüm girişleri ve sonra tüm inode'ları (dönen bir diskte) okuyarak bir performans iyileştirmesi elde edersiniz, çünkü disk kafası dizin ve inotlar arasında hareket etmez). As chmod ise aptal (diğer cevapların biri açıklar gibi) aracılığıyla çağrılmalıdır findsadece. Ancak o zaman bile, ilk yazılmadan önce tüm düğümleri okumak yardımcı olabilir (disk önbelleği için yeterli boş RAM'e sahip olduğunuzu varsayarak). Bunu öneririm:

find . -printf "" # reading the file names only
find . ! -perm 775 -printf "" # reading all the inodes (file names are cached)
find . ! -perm 775 -exec chmod 775 + # writing to the cache without reading from disk

İyi çözüm: ACL'ler

İyi çözüm tamamen farklı olabilir: Dosyalar bu dizinde oluşturulursa (ve başka bir yerden taşınmazsa), ACL'ler işi anında yapabilir. Üst dizinde varsayılan ACL'leri ayarlamanız yeterlidir.

Dosya sistemi optimizasyonlarıyla daha da iyileştirme sağlanabilir. Ext3 / ext4 ise,e2fsck -D , zaman zaman . Belki bu dizini ayrı bir birime koymak yardımcı olabilir. Farklı dosya sistemlerini veya dosya sistemi ayarlarını deneyebilirsiniz (örn. Farklı inode boyutları).


Bir NFSv4 montajı üzerinde çalışmadığınız sürece ACL'ler iyidir.
ostrokach

findÇözelti yaklaşık, zamanımı iki katına chmodbir liman işçisi kap içine ing.
Nathan ReinstateMonica Arthur

8

Kullanımını varsayarsak chmodgelen GNU coreutils paketiyle Ubuntu 12.10 üzerinde.

chmod 775 . -Rfchmodatizinlerin değişmesi gerekip gerekmediğine bakılmaksızın bulduğu her dosya için sistem çağrısını yürütür . Bu kodu inceleyerek ve strace chmod 775 . -Rgerçek davranışı listelemek için (aşağıda snippet) kullanarak bunu doğruladım .

newfstatat(4, "d", {st_mode=S_IFREG|0666, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
fchmodat(4, "d", 0775)                  = 0
newfstatat(4, "c", {st_mode=S_IFREG|0666, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
fchmodat(4, "c", 0775)                  = 0
newfstatat(4, "a", {st_mode=S_IFREG|0666, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
fchmodat(4, "a", 0775)                  = 0
newfstatat(4, "b", {st_mode=S_IFREG|0666, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
fchmodat(4, "b", 0775)                  = 0

fchmodatHer dosya üzerinde çalışmanın birkaç dezavantajı vardır

  • Çok sayıda dosya değiştirilirse, ekstra sistem çağrısı önemli hale gelecektir. find/ xargs/chmod Başkaları tarafından bahsedilen yöntem büyük olasılıkla yalnızca değiştirilmesi gerektiğini dosyaları değiştirerek daha hızlı olacaktır.
  • Çağrı fchmodat dosyanın dosya durumu değişikliğini (ctime) değiştirme . Bu, her dosya / inode'un her seferinde değişmesine neden olur ve büyük olasılıkla fazla disk yazılmasına neden olur. Bu fazla yazmaları durdurmak için bağlama seçeneklerini kullanmak mümkün olabilir.

Basit bir deney, düz için gerçekleşen ctime değişikliklerini gösterir chmod

auser@duncow:/tmp/blah.test$ ls -lc
total 0
-rwxrwxr-x 1 laptop laptop 0 Jun 18 18:17 a
-rwxrwxr-x 1 laptop laptop 0 Jun 18 18:17 b
-rwxrwxr-x 1 laptop laptop 0 Jun 18 18:17 c
-rwxrwxr-x 1 laptop laptop 0 Jun 18 18:17 d
auser@duncow:/tmp/blah.test$ chmod 775 . -R
auser@duncow:/tmp/blah.test$ ls -lc
total 0
-rwxrwxr-x 1 laptop laptop 0 Jun 18 18:25 a
-rwxrwxr-x 1 laptop laptop 0 Jun 18 18:25 b
-rwxrwxr-x 1 laptop laptop 0 Jun 18 18:25 c
-rwxrwxr-x 1 laptop laptop 0 Jun 18 18:25 d

Ancak bu, find/ xargs/ chmodbirkaç dakika sonra değişmez

auser@duncow:/tmp/blah.test$ date
Tue Jun 18 18:27:27 BST 2013
auser@duncow:/tmp/blah.test$ find . ! -perm 775 -print0 | xargs -0 -I {} chmod 775 {}
auser@duncow:/tmp/blah.test$ ls -lc
total 0
-rwxrwxr-x 1 laptop laptop 0 Jun 18 18:25 a
-rwxrwxr-x 1 laptop laptop 0 Jun 18 18:25 b
-rwxrwxr-x 1 laptop laptop 0 Jun 18 18:25 c
-rwxrwxr-x 1 laptop laptop 0 Jun 18 18:25 d

Ben her zaman find/ xargs/ chmodsürümünü kullanma eğiliminde olur çünkü find şeyler seçerken daha fazla kontrol sağlar.


1

[Source] (1), chmod(1)her zaman modu ayarlamaya çalışır ve sonra [fstatat (2)] (2) ile tekrar kontrol eder.

Dosyalar, [fts (3)] (3) yoluyla işlenir ve bu, tüm çapraz dosya sistemi nesnelerini önceden veri ağacını oluşturmak için 'stat' etmek zorundadır.

Unixlore, bir / yaklaşıma chmod(1)karşı zamanlanmış bir [güzel makale] (4) içerir : ikincisi büyüklüklerle kazanır.findxargs

Burada orijinal soruya uyarlanmış komut satırı:

find . -print0 | xargs -0 chmod 775

İki sebep:

  1. Dosya sistemi geçişi, farklı çekirdeklerde bile çalışabilen iki işlem arasındaki boru üzerinden dosyalardaki işlemlerden ayrılır.

    1. fts(3)işlem en aza indirilir, çünkü xargs(1)dizin ağacını 'düzleştirir'.

Yani evet: kesinlikle find/ kullanmalısınız xargs. basit bir çözüm için.

Diğer seçenekler:

  • [Umask] (5) ve yeni dosyaları yazan işlem (ler) in kaynak koduyla oynayın.

  • Linux kullanıyorsanız, sisteminizin inotifyçekirdek alt sistemini etkinleştirmiş olması ihtimali vardır . Bu durumda, [inotifywait (1)] (6) aracılığıyla etkili bir çözüm yazabilirsiniz.


Sidenote: Dosyalarınızda izinleri yürütmek istemiyorsanız, çağrıyı şu şekilde değiştirmenizi öneririm:

find . -type f -print0 | xargs -0 chmod 664
find . -type d -print0 | xargs -0 chmod 775

Editörlere not: Ne diğer yazılara yorum yapmak için ne yazı daha iki bağlantı eklemek için izin verilmiyor. URL'leri burada bırakıyorum ve yeterli üne sahip bazı açık kalpli kullanıcıların onları metne geri koyduğunu ve bu paragrafı sildiğini umuyorum.


Disk önbelleğini kullanıma hazırlama hakkında yorum yapmafind . -printf "" :

Bu, aşağıdaki chmodişlemlerin yürütülmesini hızlandırabilir , ancak kullanılabilir belleğe ve g / Ç yüküne bağlıdır. Yani işe yarayıp yaramayabilir. Çapraz geçiş ( find) ve chmodişlem zaten önbelleğe alınmasını sağlar, bu nedenle önbelleği hazırlamak gereksiz olabilir.

  1. https + lingrok.org / Xref / coreutils / src / chmod.c # process_file
  2. https + linux.die.net / man / 2 / fstatat
  3. https + linux.die.net / erkek / 3 / fts
  4. http + www.unixlore.net / makaleler / hız-up-toplu dosya operations.html
  5. https + en.wikipedia.org / wiki / Umask
  6. https + linux.die.net / erkek / 1 / inotifywait

0

Dosyayı oluşturan işlemleri 0775 moduyla oluşturmak için değiştirmeyi düşündünüz mü? Ortamdaki umask değerine bakın - 0002 yardımcı olabilir.

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.