chmod permissão recursiva em milhares de arquivos

13

Esta é uma pergunta mais geral sobre 'chmoding' recursivamente.

Eu tenho este script que em algum momento precisa alterar as permissões recursivamente em uma pasta que tem algumas centenas de milhares de arquivos. Há novos arquivos adicionados nessa pasta todos os dias, mas os que já estão lá têm as permissões já configuradas e não mudam.

Minha pergunta é ... quando eu ligo

chmod 775 . -R 

ele tenta definir a permissão para os arquivos que já possuem as permissões corretas definidas ou apenas para os novos arquivos que não têm as permissões corretas?

Parece que sempre demora para passar este comando no script, mesmo que os 'novos' arquivos sejam apenas alguns milhares e ele deve fazer suas permissões rapidamente.

Eu olhei para a página man do chmod, mas não parece mencionar nada sobre este caso.

Se chmod não verificar as permissões de antemão, devo começar a procurar combinar 'find' com 'chmod'?

    
por Titi Dumi 18.06.2013 / 18:38

5 respostas

7

chmod pode ou não alterar as permissões de arquivos que já estão definidos para o que você deseja, mas se não, ainda será necessário verificá-los para ver quais são as permissões atuais [0]. Com centenas de milhares de arquivos, não acho que importaria de nenhuma maneira; provavelmente o tempo será gasto pelas ferramentas stat ing de cada arquivo.

Você pode tentar usar find para verificar arquivos mais recentes que a última execução ou arquivos que precisam de chmod para serem executados, mas não acho que você terá muita melhoria de velocidade.

Se possível para o seu script, você pode conseguir colocar os novos arquivos em um diretório separado primeiro, como uma área de "retenção". Então você pode chmod THAT diretório (que só tem novos arquivos), e mv deles com o resto. Isso deve ser substancialmente mais rápido, mas infelizmente não funcionará para todas as aplicações.

[0] Mesmo que tente definir a permissão de arquivos que não precisam de alterações, o sistema de arquivos subjacente provavelmente não fará nada com a solicitação, porque é desnecessário.

    
por 18.06.2013 / 18:48
11

encontre / otimização de chmod

Tanto find quanto chmod precisam ler

  1. todas as entradas de diretório
  2. os inodes de todas essas entradas

Você provavelmente obterá uma melhoria de desempenho lendo primeiro todas as entradas e depois todos os inodes (em um disco giratório), porque a cabeça do disco não se move entre o diretório e os inodes). Como chmod é estúpido (como uma das outras respostas explica), ele deve ser chamado apenas por find . Mas, mesmo assim, pode ajudar a ler todos os inodes antes que o primeiro seja escrito (supondo que você tenha RAM livre suficiente para o cache de disco). Eu sugiro isso:

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

A boa solução: ACLs

A boa solução pode ser completamente diferente: se os arquivos forem criados nesse diretório (e não forem movidos de outro lugar), as ACLs poderão executar o trabalho rapidamente. Você só precisa definir as ACLs padrão no diretório pai.

Melhorias adicionais podem ser alcançadas pelas otimizações do sistema de arquivos. Se for ext3 / ext4, você poderá executar e2fsck -D de tempos em tempos. Talvez isso ajude a colocar esse diretório em um volume separado. Você pode experimentar diferentes sistemas de arquivos ou configurações do sistema de arquivos (por exemplo, diferentes tamanhos de inodes).

    
por 18.06.2013 / 19:22
8

Assumindo o uso de chmod do pacote GNU coreutils no Ubuntu 12.10.

chmod 775 . -R executa a chamada do sistema fchmodat para cada arquivo que ele encontra, independentemente de as permissões precisarem ser alteradas ou não. Confirmei isso inspecionando o código e usando strace chmod 775 . -R (snippet abaixo) para listar o comportamento real.

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

Existem algumas desvantagens de executar fchmodat em cada arquivo

  • A chamada extra do sistema provavelmente se tornará significativa se um grande número de arquivos for alterado. O método find / xargs / chmod mencionado por outros provavelmente será mais rápido mudando apenas os arquivos que precisam ser alterados.
  • A chamada para fchmodat altera a modificação do status do arquivo (ctime) de cada arquivo. Isso fará com que cada arquivo / inode mude a cada vez e provavelmente causará excesso de gravações em disco. Pode ser possível usar opções de montagem para parar essas gravações em excesso.

Uma experiência simples mostra as alterações da hora que acontecem para 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

Mas isso não muda para find / xargs / chmod alguns minutos depois

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

Eu sempre costumo usar a versão find / xargs / chmod , pois o Google dá mais controle sobre a seleção de itens.

    
por 18.06.2013 / 19:32
1

A [fonte] (1) mostra que chmod(1) sempre tenta definir o modo e, em seguida, verifica novamente com [fstatat (2)] (2).

Os arquivos são processados via [fts (3)] (3), que tem que 'stat' todos os percorridos objetos do sistema de arquivos de antemão para construir sua árvore de dados.

O Unixlore apresenta um [nice article] (4) em que chmod(1) é cronometrado contra uma abordagem find / xargs : esta última ganha por magnitudes.

Aqui, a linha de comando foi adaptada para a pergunta original:

find . -print0 | xargs -0 chmod 775

Duas razões:

  1. A passagem do sistema de arquivos é dissociada das operações nos arquivos via o pipe entre os dois processos, que pode até ser executado em núcleos diferentes.

    1. fts(3) operação é minimizada, porque xargs(1) 'achata' a árvore de diretórios.

Então, sim: você definitivamente deve usar find / xargs . por um simples solução.

Outras opções:

  • Jogue com o [umask] (5) e o código-fonte do (s) processo (s) escrito (s) os novos arquivos.

  • Se você estiver usando o Linux, provavelmente o seu sistema ativou o % subsistema de kernelinotify. Nesse caso, você pode criar um script solução eficiente via [inotifywait (1)] (6).

Sidenote: a menos que você queira permissões de execução em seus arquivos, eu sugira modificar a invocação da seguinte forma:

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

Nota para os editores: Eu não tenho permissão para adicionar mais do que dois links para o post, nem para comentar em outros posts. Eu deixo os URLs aqui e espero que algum usuário de coração aberto com reputação suficiente os coloque de volta no texto e apague este parágrafo.

Comente sobre preparando o cache de disco com find . -printf "" :

Isso pode acelerar a execução das seguintes operações chmod , mas depende da memória disponível e da carga de i / o. Então pode funcionar ou não. A operação de desacoplamento de traversal ( find ) e chmod já fornece o armazenamento em cache, portanto, preparar o cache pode ser supérfluo.

  1. link
  2. link
  3. link
  4. link
  5. link
  6. link
por 01.02.2017 / 00:30
0

Você já pensou em mudar o (s) processo (s) que cria o arquivo para tê-los criado com o modo 0775? Veja no valor de umask no ambiente - 0002 pode ajudar.

    
por 18.06.2013 / 20:18