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 rsync
u 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 $DIR
Parece funcionar bien y es muy probable que sea el más rápido, se mire como se mire.
(Lo verifiqué strace
y solo haceuno fchmodat()
syscall por archivo/directorio (para archivos con 644 y para directorios con 755).
El truco es el X
permiso, documentado en man chmod
, que actúa x
solo 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 chmod
procesos 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 chmod
comando. 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
find
en 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 find
comando, 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 chmod
procesos 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, find
la 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 find
pausar su comportamiento de búsqueda -exec
, los resultados encontrados se envían a xargs
para 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 chmod
comando 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 777
permisos, como las condiciones iniciales de la pregunta.
Luego, comparé los comandos diez veces, y cada vez restauré los permisos 777
antes chmod -R 0777 "$(pwd)"
de ejecutar la prueba.
Al OUTPUT
representar 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á find
conectar xargs
con chmod
:
find /base/dir -type d -print0 | xargs -0 chmod 755
find /base/dir -type f -print0 | xargs -0 chmod 644