autorizzazione ricorsiva chmod su migliaia di file


16

Questa è una domanda più generale sulla "codifica" ricorsiva.

Ho questo script che ad un certo punto ha bisogno di cambiare le autorizzazioni in modo ricorsivo in una cartella che ha alcune centinaia di migliaia di file. Ci sono nuovi file aggiunti in quella cartella ogni giorno, ma quelli che sono già lì hanno le autorizzazioni già impostate e non cambiano.

La mia domanda è ... quando chiamo

chmod 775. -R

tenta di impostare le autorizzazioni per i file che hanno già le autorizzazioni giuste impostate o solo per i nuovi file che non dispongono delle autorizzazioni giuste?

Sembra che ci voglia sempre tempo per superare questo comando nello script, anche se i "nuovi" file sono solo poche migliaia e dovrebbero fare i loro permessi abbastanza rapidamente.

Ho guardato la pagina man di chmod, ma non sembra menzionare nulla in questo caso.

Se chmod non verifica preventivamente le autorizzazioni, dovrei iniziare a cercare di combinare "find" con "chmod"?


3
Mi chiedo se è davvero più lento controllare le autorizzazioni e modificarle se non sono corrette piuttosto che impostarle direttamente sul valore corretto.
Lgeorget,

1
se qualcuno si imbatte in questo e vuole il comando find + chmod, eccolo: find. ! -perm 775 -print0 | xargs -0 -I {} chmod 775 {}
Titi Dumi,

@lgeorget, quindi stai dicendo che è più lento usare find | chmod? che semplicemente per cambiare tutto. (scusa, non ho capito dal tuo commento). salute
Titi Dumi,

Secondo la mia modesta opinione, è probabilmente più lento in quanto ha bisogno di lanciare due processi e reindirizzare l'output del primo al secondo, ma non ne sono sicuro. Dipende dal tempo impiegato per impostare le autorizzazioni che potrebbero non essere così importanti poiché sono solo 3 byte da modificare nell'inode.
lgeorget,

1
@depquid Il problema principale relativo alle prestazioni qui è la lettura dei dati nella cache del disco. Dopo la prima esecuzione, tutto è nella cache del disco (a meno che non vi sia memoria insufficiente), quindi si stanno testando le prestazioni di qualcosa che non è il collo di bottiglia nella situazione reale.
Hauke ​​Laging,

Risposte:


9

chmodpotrebbe o meno modificare le autorizzazioni dei file che sono già impostati su ciò che si desidera, ma in caso contrario, sarà comunque necessario controllarli per vedere quali sono le autorizzazioni correnti [0]. Con centinaia di migliaia di file, non penso che avrebbe importanza in entrambi i casi; molto probabilmente il tempo viene impiegato dagli strumenti in statogni file.

Puoi provare a utilizzare findper verificare la presenza di file più recenti dell'ultima esecuzione o di file che devono chmodessere eseguiti, ma non credo che otterrai un miglioramento della velocità.

Se possibile per il tuo script, potresti essere in grado di inserire prima i nuovi file in una directory separata, come area di "attesa". Quindi puoi quella chmoddirectory (che ha solo nuovi file), e mvloro insieme con il resto. Dovrebbe essere sostanzialmente più veloce, ma sfortunatamente non funzionerà per ogni applicazione.

[0] Anche se tenta di impostare l'autorizzazione per i file che non richiedono modifiche, il file system sottostante probabilmente non farà nulla con la richiesta, perché non è necessario.


Grazie per quello Proverò a trovare | versione chmod e vedere se rende le cose più veloci. In caso contrario, proverò a modificare lo script per implementare una cartella "in attesa" come suggerito.
Titi Dumi,

Il motivo per cui non si otterrebbe un miglioramento della velocità è che l'inode deve essere letto sia per il ctime che per i diritti di accesso.
Hauke ​​Laging,

10

ottimizzazione find / chmod

Entrambi finde chmoddevono leggere

  1. tutte le voci della directory
  2. gli inode per tutte queste voci

Probabilmente si ottiene un miglioramento delle prestazioni leggendo prima tutte le voci e poi tutti gli inode (su un disco rotante) perché la testa del disco non si sposta tra la directory e gli inode). Come chmod è stupido (come spiega una delle altre risposte) dovrebbe essere chiamato findsolo. Ma anche in questo caso può essere utile leggere tutti gli inode prima che il primo venga scritto (supponendo che si disponga di RAM sufficiente per la cache del disco). Suggerisco questo:

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

La buona soluzione: ACL

La buona soluzione potrebbe essere completamente diversa: se i file vengono creati in questa directory (e non spostati da qualche altra parte), gli ACL possono fare il lavoro al volo. Devi solo impostare gli ACL predefiniti nella directory principale.

Ulteriori miglioramenti possono essere raggiunti dalle ottimizzazioni del filesystem. Se è ext3 / ext4, è possibile eseguire e2fsck -Ddi tanto in tanto. Forse aiuta a mettere questa directory su un volume separato. È possibile provare diversi file system o impostazioni del file system (ad es. Dimensioni dell'inode diverse).


Gli ACL sono validi fintanto che non si lavora su una montatura NFSv4.
ostrokach,

La findsoluzione circa raddoppiò il mio tempo, chmoding in un contenitore docker.
Nathan Reinstate Monica Arthur,

8

Supponendo che l'uso di chmoddal pacchetto coreutils GNU su Ubuntu 12.10.

chmod 775 . -Resegue la fchmodatchiamata di sistema per ciascun file trovato indipendentemente dal fatto che le autorizzazioni debbano essere modificate o meno. L'ho confermato sia ispezionando il codice che utilizzando strace chmod 775 . -R(frammento di seguito) per elencare il comportamento effettivo.

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

Ci sono un paio di svantaggi nell'esecuzione fchmodatsu ogni file

  • La chiamata di sistema aggiuntiva diventerà probabilmente significativa se viene modificato un numero elevato di file. Il metodo find/ xargs/ chmodmenzionato da altri sarà probabilmente più veloce cambiando solo i file che devono essere modificati.
  • La chiamata per fchmodatmodificare la modifica dello stato del file (ctime) di ciascun file. Ciò farà cambiare ogni file / inode ogni volta e probabilmente causerà scritture in eccesso del disco. Potrebbe essere possibile utilizzare le opzioni di montaggio per interrompere queste scritture in eccesso.

Un semplice esperimento mostra i cambiamenti di ctime in corso per straight 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

Ma questo non cambia per find/ xargs/ chmodpochi minuti dopo

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

Tenderei sempre ad usare la versione find/ xargs/ chmodperché find dà più controllo sulla selezione delle cose.


1

chmod(1)Viene visualizzato [source] (1), che tenta sempre di impostare la modalità e quindi ricontrolla con [fstatat (2)] (2).

I file vengono elaborati tramite [fts (3)] (3), che deve "stat" in anticipo tutti gli oggetti del file system attraversati per creare il suo albero di dati.

Unixlore presenta un [bell'articolo] (4) in cui chmod(1)è cronometrato contro un approccio find/ xargs: quest'ultimo vince per grandezza.

Ecco la riga di comando adattata alla domanda originale:

find . -print0 | xargs -0 chmod 775

Due motivi:

  1. Il traversal del file system viene disaccoppiato dalle operazioni sui file tramite la pipe tra i due processi, che potrebbero anche essere eseguiti su core diversi.

    1. fts(3)l'operazione è ridotta al minimo, poiché xargs(1)"appiattisce" l'albero delle directory.

Quindi sì: dovresti assolutamente usare find/ xargs. per una soluzione semplice.

Altre opzioni:

  • Gioca con [umask] (5) e il codice sorgente del processo (i) che scrive i nuovi file.

  • Se stai usando Linux, è probabile che il tuo sistema abbia abilitato il inotifysottosistema kernel. In questo caso, puoi scrivere una soluzione efficiente tramite [inotifywait (1)] (6).


Sidenote: a meno che tu non voglia eseguire permessi sui tuoi file, suggerirei di modificare l'invocazione così:

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

Nota per i redattori: non sono autorizzato ad aggiungere più di due link al post, né a commentare altri post. Lascio qui gli URL e spero che un utente di buon cuore con una reputazione sufficiente li riporti nel testo e cancelli questo paragrafo.


Commenta l' innesco della cache del disco con find . -printf "":

Ciò potrebbe accelerare l'esecuzione delle seguenti chmodoperazioni, tuttavia dipende dalla memoria disponibile e dal carico di I / O. Quindi potrebbe funzionare o no. Il disaccoppiamento traversal ( find) e l' chmodoperazione prevede già la memorizzazione nella cache, quindi l'adescamento della cache potrebbe essere superfluo.

  1. https + lingrok.org / riferimento esterno / coreutils / src / chmod.c # process_file
  2. https + linux.die.net / uomo / 2 / fstatat
  3. https + linux.die.net / uomo / 3 / FTS
  4. http + www.unixlore.net / articoli / accelerare-up-bulk-file-operations.html
  5. https + en.wikipedia.org / wiki / Umask
  6. https + linux.die.net / uomo / 1 / inotifywait

0

Hai mai pensato di cambiare i processi che creano il file per averli creati con la modalità 0775? Guarda il valore umask nell'ambiente - 0002 può essere d'aiuto.

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.