Linux ext4 restaura direitos de acesso a arquivos e diretórios após backup/restauração incorretos

Linux ext4 restaura direitos de acesso a arquivos e diretórios após backup/restauração incorretos

Eu meio que estraguei o backup do meu diretório pessoal rsync(talvez porque estou fazendo backup em um sistema de arquivos NTFS): todos os arquivos estão aqui, mas todos os direitos de acesso a arquivos e diretórios são 777. Eu queria saber se havia umMagiautilitário que mudaria recursivamente:

  • os diretórios de 777 a 755.
  • os arquivos normais de 777 a 644. Não tenho muitos executáveis ​​em minha casa, então posso gerenciar isso manualmente mais tarde.
  • deixe outros arquivos (links, mais alguma coisa?) Inalterados.

Fazer isso com casca é fácil, mas levará horas...

Pergunta subsidiária: algum conselho para fazer backup adequadamente de uma hierarquia de diretórios Linux em NTFS (com rsyncou outro).

Responder1

A solução padrão recomendada é direta:

find . -type d -exec chmod 0755 "{}" \+
find . -type f -exec chmod 0644 "{}" \+

Isso acrescentará tantos nomes de arquivos quanto possível como argumentos a um único comando, até o comprimento máximo da linha de comando do sistema. Se a linha exceder esse comprimento, o comando será chamado várias vezes.

Se quiser chamar o comando uma vez por arquivo, você pode fazer:

find . -type d -exec chmod 0755 "{}" \;
find . -type f -exec chmod 0644 "{}" \;

Responder2

chmod -R a=,u+rwX,go+rX $DIRparece funcionar bem e é muito provável que seja o mais rápido, independentemente de como você olha para ele.

(Eu verifiquei com strace, e isso faz apenasum fchmodat()syscall por arquivo/diretório - para arquivos com 644 e para diretórios com 755).

O truque é a Xpermissão, documentada em man chmod, que funciona xapenas para diretórios - a mesma distinção que você queria.

O que énãodocumentado é meu palpite de que eles seriam aplicados na mesma sequência em que são especificados, e não apenas em alguma ordem aleatória, mas testes repetidos com diversas variantes me convenceram de que eles realmente são executados na ordem dada, então tenho certeza isso sempre vai funcionar assim.

Devo mencionar que isso ocorre no Linux, embora uma leitura superficial da página de manual do BSD para chmod sugira quedevetrabalhar lá também.

Responder3

Eu compareiresposta do sitaram,Comentário de Peter Cordes,Resposta do Fanático, eresposta de harrymc, masesta resposta tem o caminho mais rápido.

Médias:

  • Resposta de Deltik* – 7.480 segundos
    * Crédito paraPedro Cordesparasugerindo paralelismo
  • resposta do sitaram – 12,962 segundos (73,275% mais lento que o melhor)
  • Comentário de Peter Cordes – 14,414 segundos (92,685% mais lento que o melhor)
  • Resposta de Fanatique – 14,570 segundos (94,772% mais lento que o melhor)
  • resposta atualizada de harrymc – 14,791 segundos (97,730% mais lento que o melhor)
  • resposta original de harrymc – 1.061,926 segundos (14.096,113% mais lento que o melhor)

Resumo estatístico completo:

Author              N      min     q1      median  q3      max     mean    stddev
------------------  --     ------- ------- ------- ------- ------- ------- --------
Deltik              10     7.121   7.3585  7.4615  7.558   8.005   7.4804  0.248965
sitaram             10     12.651  12.803  12.943  13.0685 13.586  12.9617 0.276589
Peter Cordes        10     14.096  14.2875 14.375  14.4495 15.101  14.4136 0.269732
Fanatique           10     14.219  14.512  14.5615 14.6525 14.892  14.5697 0.211788
harrymc (updated)   10     14.38   14.677  14.8595 14.9025 15.119  14.791  0.21817
harrymc (original)  1      1061.93 1061.93 1061.93 1061.93 1061.93 1061.93 N/A

Comando do Deltik, em formato de benchmark:

encontre "$(pwd)" -type d -print0 | xargs -0 -P4 chmod 755 &\
encontre "$(pwd)" -type f -print0 | xargs -0 -P4 chmod 644 e espere

Comando do sitaram, em formato de benchmark:

chmod -R a=,u+rwX,go+rX "$(pwd)"

Comando de Peter Cordes, em formato de benchmark:

encontre "$(pwd)" \( -type d -exec chmod 755 {} + \) \
           -o \( -type f -exec chmod 644 {} + \)

Comando do Fanatique, em formato de benchmark:

encontre "$(pwd)" -type d -print0 | xargs -0 chmod 755; \
encontre "$(pwd)" -type f -print0 | xargs -0 chmod 644

Comando atualizado de harrymc, em formato de benchmark:

encontre "$(pwd)" -type d -exec chmod 755 {} + ; \
encontre "$(pwd)" -type f -exec chmod 644 {} +

Comando original de harrymc, em formato de benchmark:

encontre "$(pwd)" -type d -exec chmod 755 {} \; ; \
encontre "$(pwd)" -type f -exec chmod 644 {} \;

Meu comando foi o mais rápido graças aos quatro chmodprocessos paralelos por tipo de arquivo. Isso permitiu a execução de vários núcleos de CPU chmod, o que move o gargalo para os threads de E/S do kernel ou para o disco.

O comando do sitaram foi o vice-campeão porque tudo é feito dentro do chmodcomando. Isso reduz substancialmente a sobrecarga em comparação com as outras respostas porque:

  • Os arquivos só precisam ser verificados uma vez (semelhante a fazer um findem vez de dois) e
  • Nenhum processo filho precisa ser criado.

Este comando é o menos flexível, entretanto, porque se baseia em um truque que envolve o significado diferente do bit executável entre arquivos e diretórios regulares.

O comentário de Peter Cordes, que usa um findcomando, evita pesquisas duplas de entradas de diretório. Quanto mais arquivos houver, mais substancial será essa melhoria. Ele ainda tem a sobrecarga de criação chmodde processos filhos, e é por isso que é um pouco mais lento que a chmodsolução -only.

Entre o comando do Fanatique e o comando atualizado do harrymc, finda canalização para xargs( find | xargs) foi mais rápida porque o fluxo de resultados é processado de forma assíncrona. Em vez de findpausar seu comportamento de localização para -exec, os resultados encontrados são enviados xargspara processamento simultâneo.
(O delimitador de byte nulo ( find -print0 | xargs -0) não parece afetar o tempo de execução.)

O comando original de harrymc era muito lento devido à sobrecarga de um novo chmodcomando para cada arquivo e pasta, cada um executado em sequência.


Na configuração de teste, havia 1.000.002 arquivos regulares contidos em 1.001 diretórios:

root@demo:~# echo {0..999} | xargs mkdir-p
root@demo:~# find -type d -exec bash -c "cd {}; echo {0..999} | xargs touch" \;
root@demo:~# encontrar | wc-l
1001003
root@demo:~# find -type d | wc-l
1001
root@demo:~# find -type f | wc-l
1000002

Defino todos os arquivos e pastas para terem 777permissões, conforme as condições iniciais da pergunta.

Em seguida, comparei os comandos dez vezes, cada vez restaurando as permissões 777antes chmod -R 0777 "$(pwd)"de executar o teste.

Representando OUTPUTum arquivo que contém a saída de cada comando de benchmark, calculei o tempo médio usando:

bc <<< "scale=3; ($(grep real OUTPUT | grep -Po '(?<=m).*(?=s)' | xargs | sed 's/ /+/g'))/10"

Resultados do benchmark da resposta da Deltik

root@demo:~# for i in {0..9} ; faça chmod -R 0777 "$(pwd)"; tempo {encontre "$(pwd)" -type d -print0 | xargs -0 -P4 chmod 755 e encontre "$(pwd)" -type f -print0 | xargs -0 -P4 chmod 644 & espere; } ; feito
[1] 9791
[2] 9793
[1]- Concluído, encontre "$(pwd)" -type d | xargs -P4 chmod 755
[2]+ Concluído, encontre "$(pwd)" -type f | xargs -P4 chmod 644

0m7.634s reais
usuário 0m2.536s
sistema 0m23.384s
[1] 9906
[2] 9908
[1]- Concluído, encontre "$(pwd)" -type d | xargs -P4 chmod 755
[2]+ Concluído, encontre "$(pwd)" -type f | xargs -P4 chmod 644

0m7.443s reais
usuário 0m2.636s
sistema 0m23.106s
[1] 10021
[2] 10023
[1]- Concluído, encontre "$(pwd)" -type d | xargs -P4 chmod 755
[2]+ Concluído, encontre "$(pwd)" -type f | xargs -P4 chmod 644

0m8.005s reais
usuário 0m2.672s
sistema 0m24.557s
[1] 10136
[2] 10138
[1]- Concluído, encontre "$(pwd)" -type d | xargs -P4 chmod 755
[2]+ Concluído, encontre "$(pwd)" -type f | xargs -P4 chmod 644

0m7.480s reais
usuário 0m2.541s
sistema 0m23.699s
[1] 10251
[2] 10253
[1]- Concluído, encontre "$(pwd)" -type d | xargs -P4 chmod 755
[2]+ Concluído, encontre "$(pwd)" -type f | xargs -P4 chmod 644

0m7.397s reais
usuário 0m2.558s
sistema 0m23.583s
[1] 10366
[2] 10368
[1]- Concluído, encontre "$(pwd)" -type d | xargs -P4 chmod 755
[2]+ Concluído, encontre "$(pwd)" -type f | xargs -P4 chmod 644

0m7.482s reais
usuário 0m2.601s
sistema 0m23.728s
[1] 10481
[2] 10483
[1]- Concluído, encontre "$(pwd)" -type d | xargs -P4 chmod 755
[2]+ Concluído, encontre "$(pwd)" -type f | xargs -P4 chmod 644

0m7.679s reais
usuário 0m2.749s
sistema 0m23.395s
[1] 10596
[2] 10598
[1]- Concluído, encontre "$(pwd)" -type d | xargs -P4 chmod 755
[2]+ Concluído, encontre "$(pwd)" -type f | xargs -P4 chmod 644

0m7.243s reais
usuário 0m2.583s
sistema 0m23.400s
[1] 10729
[2] 10731
[1]- Concluído, encontre "$(pwd)" -type d | xargs -P4 chmod 755
[2]+ Concluído, encontre "$(pwd)" -type f | xargs -P4 chmod 644

0m7.320s reais
usuário 0m2.640s
sistema 0m23.403s
[1] 10844
[2] 10847
[1]- Concluído, encontre "$(pwd)" -type d | xargs -P4 chmod 755
[2]+ Concluído, encontre "$(pwd)" -type f | xargs -P4 chmod 644

0m7.121s reais
usuário 0m2.490s
sistema 0m22.943s

Tempo médio: 7.480 segundos

Resultados do benchmark da resposta do sitaram

root@demo:~# for i in {0..9} ; faça chmod -R 0777 "$(pwd)"; tempo chmod -R a=,u+rwX,go+rX "$(pwd)" ; feito

0m12.860s reais
usuário 0m0.940s
sistema 0m11.725s

reais 0m13.059s
usuário 0m0.896s
sistema 0m11.937s

0m12.819s reais
usuário 0m0.945s
sistema 0m11.706s

reais 0m13.078s
usuário 0m0.855s
sistema 0m12.000s

0m12.653s reais
usuário 0m0.856s
sistema 0m11.667s

0m12.787s reais
usuário 0m0.820s
sistema 0m11.834s

0m12.651s reais
usuário 0m0.916s
sistema 0m11.578s

reais 0m13.098s
usuário 0m0.939s
sistema 0m12.004s

reais 0m13.586s
usuário 0m1.024s
sistema 0m12.372s

reais 0m13.026s
usuário 0m0.976s
sistema 0m11.910s

Tempo médio: 12,962 segundos

Resultados do benchmark do comentário de Peter Cordes

root@demo:~# for i in {0..9} ; faça chmod -R 0777 "$(pwd)"; hora encontrar "$(pwd)" \( -type d -exec chmod 755 {} + \) -o \( -type f -exec chmod 644 {} + \) ; feito

reais 0m14.096s
usuário 0m1.455s
sistema 0m12.456s

0m14.492s reais
usuário 0m1.398s
sistema 0m12.897s

0m14.309s reais
usuário 0m1.518s
sistema 0m12.576s

0m14.451s reais
usuário 0m1.477s
sistema 0m12.776s

0m15.101s reais
usuário 0m1.554s
sistema 0m13.378s

0m14.223s reais
usuário 0m1.470s
sistema 0m12.560s

0m14.266s reais
usuário 0m1.459s
sistema 0m12.609s

0m14.357s reais
usuário 0m1.415s
sistema 0m12.733s

0m14.393s reais
usuário 0m1.404s
sistema 0m12.830s

0m14.448s reais
usuário 0m1.492s
sistema 0m12.717s

Tempo médio: 14,414 segundos

Resultados do benchmark da resposta do Fanatique

root@demo:~# for i in {0..9} ; faça chmod -R 0777 "$(pwd)"; tempo {encontre "$(pwd)" -type d -print0 | xargs -0 chmod 755; encontre "$(pwd)" -type f -print0 | xargs -0 chmod 644; } ; feito

0m14.561s reais
usuário 0m1.991s
sistema 0m13.343s

0m14.521s reais
usuário 0m1.958s
sistema 0m13.352s

0m14.696s reais
usuário 0m1.967s
sistema 0m13.463s

reais 0m14.562s
usuário 0m1.875s
sistema 0m13.400s

0m14.609s reais
usuário 0m1.841s
sistema 0m13.533s

0m14.892s reais
usuário 0m2.050s
sistema 0m13.630s

0m14.291s reais
usuário 0m1.885s
sistema 0m13.182s

0m14.843s reais
usuário 0m2.066s
sistema 0m13.578s

0m14.219s reais
usuário 0m1.837s
sistema 0m13.145s

0m14.503s reais
usuário 0m1.803s
sistema 0m13.419s

Tempo médio: 14.570 segundos

Resultados do benchmark da resposta atualizada de harrymc

root@demo:~# for i in {0..9} ; faça chmod -R 0777 "$(pwd)"; tempo {encontre "$(pwd)" -type d -exec chmod 755 {} + ; encontre "$(pwd)" -type f -exec chmod 644 {} + ; } ; feito

0m14.975s reais
usuário 0m1.728s
sistema 0m13.050s

0m14.710s reais
usuário 0m1.586s
sistema 0m12.979s

0m14.644s reais
usuário 0m1.641s
sistema 0m12.872s

0m14.927s reais
usuário 0m1.706s
sistema 0m13.036s

0m14.867s reais
usuário 0m1.597s
sistema 0m13.086s

0m15.119s reais
usuário 0m1.666s
sistema 0m13.259s

0m14.878s reais
usuário 0m1.590s
sistema 0m13.098s

0m14.852s reais
usuário 0m1.681s
sistema 0m13.045s

0m14.380s reais
usuário 0m1.603s
sistema 0m12.663s

0m14.558s reais
usuário 0m1.514s
sistema 0m12.899s

Tempo médio: 14,791 segundos

Resultados do benchmark da resposta original de Harrymc

Devido à lentidão desse comando, executei o benchmark apenas uma vez.

root@demo:~# for i in {0..0} ; faça chmod -R 0777 "$(pwd)"; tempo {encontre "$(pwd)" -type d -exec chmod 755 {} \; ; encontre "$(pwd)" -type f -exec chmod 644 {} \; ; } ; feito
 
17m41.926s reais
usuário 12m26.896s
sistema 4m58.332s

Tempo gasto: 1.061,926 segundos

Responder4

Se os diretórios forem muito grandes e contiverem muitos arquivos, a maneira original que @harrymc mostrou irá falhar.

Se você tiver muitos arquivos, precisará findcanalizar xargs:chmod

find /base/dir -type d -print0 | xargs -0 chmod 755 
find /base/dir -type f -print0 | xargs -0 chmod 644

informação relacionada