Use el comando chmod selectivamente

11

Quiero establecer el permiso 755 en todos los archivos y subdirectorios en un directorio específico, pero quiero ejecutar chmod 755 solo para aquellos componentes que no tienen permiso 755.

find /main_directory/ -exec chmod 755 {} \;

Si el findcomando devuelve una lista larga, esto llevará mucho tiempo. Sé que puedo usar el comando stat para verificar el permiso de nivel de archivo Octal de cada componente y luego usar if-else para alternar el permiso de archivo, pero ¿hay algún enfoque de línea única que use findy xargspara verificar primero qué permiso tiene el archivo / directorio? , y luego use chmodpara cambiarlo a 755 si está configurado en otra cosa.

Kumarjit Ghosh
fuente
66
Esta puede ser una optimización prematura, y puede que ni siquiera sea más rápida. Hacer todos esos controles puede ralentizarlo. Las pruebas para garantizar que sean más rápidas solo darán resultado, si tiene que hacer esto mucho.
ctrl-alt-delor
3
Probablemente no desee otorgar permisos de ejecución a todos los archivos. Esto creará un riesgo de seguridad. (Este es uno de los vectores de virus en Windows de Microsoft: todo es ejecutable). En modo simbólico se puede decir u+rw,go+r,go-w,ugo+X: tenga en cuenta la capital.
ctrl-alt-delor
Estoy de acuerdo con @ ctrl-alt-delor pero sugeriría algo más cercano a lo que pediste, u = rwX, go = rX que debería lograr lo mismo.
penguin359

Respuestas:

21

Si desea cambiar los permisos 755tanto en los archivos como en los directorios, no hay un beneficio real de usar find(al menos desde el punto de vista del rendimiento), y simplemente podría hacerlo

chmod -R 755 /main_directory

Si realmente desea usar findpara evitar cambiar los permisos en cosas que ya tienen 755permisos (para evitar actualizar su marca de tiempo ctime), entonces también debe probar los permisos actuales en cada directorio y archivo:

find /main_directory ! -perm 0755 -exec chmod 755 {} +

El -exec ... {} +va a recoger la mayor cantidad posible de nombres de ruta que pasa la ! -perm 0755prueba, y ejecutar chmoden todos ellos a la vez.

Por lo general, uno querría cambiar los permisos en archivos y directorios por separado, para que no todos los archivos sean ejecutables:

find /main_directory   -type d ! -perm 0755 -exec chmod 755 {} +
find /main_directory ! -type d ! -perm 0644 -exec chmod 644 {} +
Kusalananda
fuente
Funcionó como encanto, gracias. Saludos, Kumarjit
Kumarjit Ghosh
1
Sospecho que usar en +lugar de ;hacer una gran diferencia aquí.
Kevin
Este es el camino rápido: evite un cheque. Además, usaría find para hacer una lista de solo los archivos que tiene permiso para cambiar, esto evitará errores de chmod en archivos que no puede cambiar. <pre> <code> # rwx, rw, wx, w solo encuentra. -user $ (whoami) -perm / 002! -perm 0755 -exec chmod 0755 {} \; # romper en dos operaciones encontrar. -user $ (whoami) -perm / 002! -perm 0755> /tmp/chfiles.txt para el archivo en $ (</ tmp / chfiles.txt) do chmod --quiet 0755 "$ {file}" done </code> </pre>
Chris Reid
@ChrisReid Tenga en cuenta que recorrer una lista de nombres de ruta como esa se romperá si algún nombre de ruta contiene un espacio en blanco.
Kusalananda
Supongo que debe cambiar el separador de campo interno (IFS) a '\ n' en un script. Estas son configuraciones de entorno, la forma en que el shell las interpreta depende de los valores de esas configuraciones. Pruebo los scripts en archivos ficticios antes de usarlos para descubrir distorsiones contundentes como renombrar archivos o sobrescribirlos. Me gusta la forma shell printf de configurar IFS. IFS = $ (printf "\ n") # muy legible
Chris Reid
1

Como findobtuve la -exec ... +sintaxis, no tiene mucho sentido usarla xargs, pero a medida que la solicita:

find /main_directory -not -perm 0755 | xargs chmod 755
Henrik apoya a la comunidad
fuente
1
También tenga en cuenta que xargs sin -0(en combinación con -print0in find; que es la extensión GNU) puede ser bastante problemático en cuanto a seguridad si un atacante potencial puede crear nombres de archivo que incluyan espacios en blanco u otros caracteres especiales en ellos. Así que mejor quédate -execcuando puedas
Matija Nalis
No es necesario xargs(solo use -exec), y si lo usa, debe usar -print0/ -0como dice Matija.
Kevin