Linux ext4 restaura los derechos de acceso a archivos y directorios después de una mala copia de seguridad/restauración

Linux ext4 restaura los derechos de acceso a archivos y directorios después de una mala copia de seguridad/restauración

En cierto modo arruiné la copia de seguridad de mi directorio personal rsync(tal vez porque estoy haciendo una copia de seguridad en un sistema de archivos NTFS): todos los archivos están aquí pero todos los derechos de acceso a archivos y directorios son 777. Me preguntaba si había unmagiautilidad que cambiaría recursivamente:

  • los directorios del 777 al 755.
  • los archivos normales del 777 al 644. No tengo muchos ejecutables en mi casa, así que puedo administrarlos a mano más tarde.
  • deje los demás archivos (enlaces, ¿algo más?) sin cambios.

Hacerlo con cáscara es fácil, pero llevará horas...

Pregunta subsidiaria: algún consejo para realizar una copia de seguridad adecuada de una jerarquía de directorios de Linux en NTFS (con rsyncu otro).

Respuesta1

La solución estándar recomendada es sencilla:

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

Esto agregará tantos nombres de archivos como sea posible como argumentos a un solo comando, hasta la longitud máxima de línea de comando del sistema. Si la línea excede esta longitud, el comando se llamará varias veces.

Si desea llamar al comando una vez por archivo, puede hacer lo siguiente:

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

Respuesta2

chmod -R a=,u+rwX,go+rX $DIRParece funcionar bien y es muy probable que sea el más rápido, se mire como se mire.

(Lo verifiqué stracey solo haceuno fchmodat()syscall por archivo/directorio (para archivos con 644 y para directorios con 755).

El truco es el Xpermiso, documentado en man chmod, que actúa xsolo para directorios: la distinción que deseaba.

Qué esnoEstá documentado mi suposición de que se aplicarían en la misma secuencia en la que se especifican, y no solo en un orden aleatorio, pero las pruebas repetidas con varias variantes me han convencido de que efectivamente se ejecutan en el orden indicado, por lo que estoy bastante seguro. esto siempre va a funcionar así.

Debo mencionar que esto está en Linux, aunque una lectura superficial de la página de manual de BSD para chmod sugiere quedeberíatrabajar allí también.

Respuesta3

yo comparéla respuesta de sitaram,El comentario de Peter Cordes.,La respuesta del fanático., yla respuesta de harrymc, peroesta respuesta tiene la forma más rápida.

Promedios:

  • Respuesta de Deltik* – 7.480 segundos
    * Crédito aPedro Cordesparasugiriendo paralelismo
  • respuesta de sitaram: 12,962 segundos (73,275% más lento que el mejor)
  • Comentario de Peter Cordes: 14,414 segundos (92,685 % más lento que el mejor)
  • Respuesta de Fanatique: 14,570 segundos (94,772% más lento que el mejor)
  • Respuesta actualizada de Harrymc: 14,791 segundos (97,730% más lento que el mejor)
  • Respuesta original de Harrymc: 1061,926 segundos (14096,113% más lento que el mejor)

Resumen estadí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 de Deltik, en formato de referencia:

buscar "$(contraseña)" -tipo d -print0 | xargs -0 -P4 chmod 755 &\
buscar "$(contraseña)" -tipo f -print0 | xargs -0 -P4 chmod 644 y espera

Comando de Sitaram, en formato de referencia:

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

Comando de Peter Cordes, en formato de referencia:

busque "$(contraseña)" \( -type d -exec chmod 755 {} + \) \
           -o \( -type f -exec chmod 644 {} + \)

Comando de Fanatique, en formato de referencia:

buscar "$(contraseña)" -tipo d -print0 | xargs -0 chmod 755; \
buscar "$(contraseña)" -tipo f -print0 | xargs -0 chmod 644

Comando actualizado de harrymc, en formato de referencia:

buscar "$(contraseña)" -tipo d -exec chmod 755 {} +; \
buscar "$(contraseña)" -tipo f -exec chmod 644 {} +

Comando original de harrymc, en formato de referencia:

buscar "$(contraseña)" -tipo d -exec chmod 755 {} \; ; \
buscar "$(contraseña)" -tipo f -exec chmod 644 {} \;

Mi comando fue el más rápido gracias a los cuatro chmodprocesos paralelos por tipo de archivo. Esto permitió que se ejecutaran múltiples núcleos de CPU chmod, lo que mueve el cuello de botella hacia los subprocesos de E/S del kernel o el disco.

El comando de Sitaram quedó en segundo lugar porque todo se hace dentro del chmodcomando. Esto reduce sustancialmente los gastos generales en comparación con las otras respuestas porque:

  • Los archivos solo deben escanearse una vez (similar a hacerlo uno finden lugar de dos) y
  • No es necesario crear procesos secundarios.

Sin embargo, este comando es el menos flexible porque se basa en un truco que implica el diferente significado del bit ejecutable entre archivos y directorios normales.

El comentario de Peter Cordes, que utiliza un findcomando, evita búsquedas dobles de entradas de directorio. Cuantos más archivos haya, más sustancial será esta mejora. Todavía tiene la sobrecarga de crear chmodprocesos secundarios, por lo que es un poco más lento que la chmodúnica solución.

Entre el comando de Fanatique y el comando actualizado de harrymc, findla canalización a xargs( find | xargs) fue más rápida porque el flujo de resultados se procesa de forma asincrónica. En lugar de findpausar su comportamiento de búsqueda -exec, los resultados encontrados se envían a xargspara su procesamiento simultáneo.
(El delimitador de bytes nulos ( find -print0 | xargs -0) no pareció afectar el tiempo de ejecución).

El comando original de harrymc era demasiado lento debido a la sobrecarga de un nuevo chmodcomando para cada archivo y carpeta, cada uno ejecutado en secuencia.


En la configuración de prueba, había 1.000.002 archivos normales contenidos en 1.001 directorios:

root@demo:~# eco {0..999} | xargs mkdir -p
root@demo:~# buscar -tipo d -exec bash -c "cd {}; echo {0..999} | xargs touch" \;
root@demo:~# buscar | baño -l
1001003
root@demo:~# buscar -tipo d | baño -l
1001
root@demo:~# buscar -tipo f | baño -l
1000002

Configuré todos los archivos y carpetas para que tengan 777permisos, como las condiciones iniciales de la pregunta.

Luego, comparé los comandos diez veces, y cada vez restauré los permisos 777antes chmod -R 0777 "$(pwd)"de ejecutar la prueba.

Al OUTPUTrepresentar un archivo que contiene el resultado de cada comando de referencia, calculé el tiempo promedio usando:

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

Resultados del punto de referencia de la respuesta de Deltik.

root@demo:~# para i en {0..9}; hacer chmod -R 0777 "$(contraseña)"; tiempo { buscar "$(contraseña)" -tipo d -print0 | xargs -0 -P4 chmod 755 y busque "$(pwd)" -tipo f -print0 | xargs -0 -P4 chmod 644 y espera; } ; hecho
[1] 9791
[2] 9793
[1]- Hecho buscar "$(pwd)" -escriba d | xargs -P4 chmod 755
[2]+ Hecho buscar "$(pwd)" -tipo f | xargs -P4 chmod 644

reales 0m7.634s
usuario 0m2.536s
sistema 0m23.384s
[1] 9906
[2] 9908
[1]- Hecho buscar "$(pwd)" -escriba d | xargs -P4 chmod 755
[2]+ Hecho buscar "$(pwd)" -tipo f | xargs -P4 chmod 644

reales 0m7.443s
usuario 0m2.636s
sistema 0m23.106s
[1] 10021
[2] 10023
[1]- Hecho buscar "$(pwd)" -escriba d | xargs -P4 chmod 755
[2]+ Hecho buscar "$(pwd)" -tipo f | xargs -P4 chmod 644

reales 0m8.005s
usuario 0m2.672s
sistema 0m24.557s
[1] 10136
[2] 10138
[1]- Hecho buscar "$(pwd)" -escriba d | xargs -P4 chmod 755
[2]+ Hecho buscar "$(pwd)" -tipo f | xargs -P4 chmod 644

reales 0m7.480s
usuario 0m2.541s
sistema 0m23.699s
[1] 10251
[2] 10253
[1]- Hecho buscar "$(pwd)" -escriba d | xargs -P4 chmod 755
[2]+ Hecho buscar "$(pwd)" -tipo f | xargs -P4 chmod 644

reales 0m7.397s
usuario 0m2.558s
sistema 0m23.583s
[1] 10366
[2] 10368
[1]- Hecho buscar "$(pwd)" -escriba d | xargs -P4 chmod 755
[2]+ Hecho buscar "$(pwd)" -tipo f | xargs -P4 chmod 644

reales 0m7.482s
usuario 0m2.601s
sistema 0m23.728s
[1] 10481
[2] 10483
[1]- Hecho buscar "$(pwd)" -escriba d | xargs -P4 chmod 755
[2]+ Hecho buscar "$(pwd)" -tipo f | xargs -P4 chmod 644

reales 0m7.679s
usuario 0m2.749s
sistema 0m23.395s
[1] 10596
[2] 10598
[1]- Hecho buscar "$(pwd)" -escriba d | xargs -P4 chmod 755
[2]+ Hecho buscar "$(pwd)" -tipo f | xargs -P4 chmod 644

reales 0m7.243s
usuario 0m2.583s
sistema 0m23.400s
[1] 10729
[2] 10731
[1]- Hecho buscar "$(pwd)" -escriba d | xargs -P4 chmod 755
[2]+ Hecho buscar "$(pwd)" -tipo f | xargs -P4 chmod 644

reales 0m7.320s
usuario 0m2.640s
sistema 0m23.403s
[1] 10844
[2] 10847
[1]- Hecho buscar "$(pwd)" -escriba d | xargs -P4 chmod 755
[2]+ Hecho buscar "$(pwd)" -tipo f | xargs -P4 chmod 644

reales 0m7.121s
usuario 0m2.490s
sistema 0m22.943s

Tiempo medio: 7.480 segundos

Resultados del punto de referencia de la respuesta de Sitaram.

root@demo:~# para i en {0..9}; hacer chmod -R 0777 "$(contraseña)"; tiempo chmod -R a=,u+rwX,go+rX "$(pwd)" ; hecho

reales 0m12.860s
usuario 0m0.940s
sistema 0m11.725s

reales 0m13.059s
usuario 0m0.896s
sistema 0m11.937s

reales 0m12.819s
usuario 0m0.945s
sistema 0m11.706s

reales 0m13.078s
usuario 0m0.855s
sistema 0m12.000s

reales 0m12.653s
usuario 0m0.856s
sistema 0m11.667s

reales 0m12.787s
usuario 0m0.820s
sistema 0m11.834s

reales 0m12.651s
usuario 0m0.916s
sistema 0m11.578s

reales 0m13.098s
usuario 0m0.939s
sistema 0m12.004s

reales 0m13.586s
usuario 0m1.024s
sistema 0m12.372s

reales 0m13.026s
usuario 0m0.976s
sistema 0m11.910s

Tiempo medio: 12.962 segundos

Resultados del benchmark del comentario de Peter Cordes

root@demo:~# para i en {0..9}; hacer chmod -R 0777 "$(contraseña)"; tiempo encontrar "$(pwd)" \( -type d -exec chmod 755 {} + \) -o \( -type f -exec chmod 644 {} + \) ; hecho

reales 0m14.096s
usuario 0m1.455s
sistema 0m12.456s

reales 0m14.492s
usuario 0m1.398s
sistema 0m12.897s

reales 0m14.309s
usuario 0m1.518s
sistema 0m12.576s

reales 0m14.451s
usuario 0m1.477s
sistema 0m12.776s

reales 0m15.101s
usuario 0m1.554s
sistema 0m13.378s

reales 0m14.223s
usuario 0m1.470s
sistema 0m12.560s

reales 0m14.266s
usuario 0m1.459s
sistema 0m12.609s

reales 0m14.357s
usuario 0m1.415s
sistema 0m12.733s

reales 0m14.393s
usuario 0m1.404s
sistema 0m12.830s

reales 0m14.448s
usuario 0m1.492s
sistema 0m12.717s

Tiempo medio: 14.414 segundos

Resultados del punto de referencia de la respuesta de Fanatique.

root@demo:~# para i en {0..9}; hacer chmod -R 0777 "$(contraseña)"; tiempo { buscar "$(contraseña)" -tipo d -print0 | xargs -0 chmod 755; buscar "$(contraseña)" -tipo f -print0 | xargs -0 chmod 644; } ; hecho

reales 0m14.561s
usuario 0m1.991s
sistema 0m13.343s

reales 0m14.521s
usuario 0m1.958s
sistema 0m13.352s

reales 0m14.696s
usuario 0m1.967s
sistema 0m13.463s

reales 0m14.562s
usuario 0m1.875s
sistema 0m13.400s

reales 0m14.609s
usuario 0m1.841s
sistema 0m13.533s

reales 0m14.892s
usuario 0m2.050s
sistema 0m13.630s

reales 0m14.291s
usuario 0m1.885s
sistema 0m13.182s

reales 0m14.843s
usuario 0m2.066s
sistema 0m13.578s

reales 0m14.219s
usuario 0m1.837s
sistema 0m13.145s

reales 0m14.503s
usuario 0m1.803s
sistema 0m13.419s

Tiempo medio: 14.570 segundos

Resultados del punto de referencia de la respuesta actualizada de harrymc

root@demo:~# para i en {0..9}; hacer chmod -R 0777 "$(contraseña)"; tiempo { buscar "$(contraseña)" -tipo d -exec chmod 755 {} +; buscar "$(contraseña)" -tipo f -exec chmod 644 {} + ; } ; hecho

reales 0m14.975s
usuario 0m1.728s
sistema 0m13.050s

reales 0m14.710s
usuario 0m1.586s
sistema 0m12.979s

reales 0m14.644s
usuario 0m1.641s
sistema 0m12.872s

reales 0m14.927s
usuario 0m1.706s
sistema 0m13.036s

reales 0m14.867s
usuario 0m1.597s
sistema 0m13.086s

reales 0m15.119s
usuario 0m1.666s
sistema 0m13.259s

reales 0m14.878s
usuario 0m1.590s
sistema 0m13.098s

reales 0m14.852s
usuario 0m1.681s
sistema 0m13.045s

reales 0m14.380s
usuario 0m1.603s
sistema 0m12.663s

reales 0m14.558s
usuario 0m1.514s
sistema 0m12.899s

Tiempo medio: 14.791 segundos

Resultados del punto de referencia de la respuesta original de harrymc

Debido a lo lento que era este comando, solo ejecuté el punto de referencia una vez.

root@demo:~# para i en {0..0}; hacer chmod -R 0777 "$(contraseña)"; tiempo { buscar "$(contraseña)" -tipo d -exec chmod 755 {} \; ; buscar "$(contraseña)" -tipo f -exec chmod 644 {} \; ; } ; hecho
 
reales 17m41.926s
usuario 12m26.896s
sistema 4m58.332s

Tiempo necesario: 1061,926 segundos

Respuesta4

Si los directorios son demasiado grandes y contienen demasiados archivos, la forma original que @harrymc le mostró fallará.

Si tiene demasiados archivos, deberá findconectar xargscon chmod:

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

información relacionada