¿Cómo eliminar de forma recursiva los permisos de ejecución de los archivos sin tocar las carpetas?

42

Hice una copia de seguridad en un disco NTFS, y bueno, esta copia de seguridad realmente resultó necesaria. Sin embargo, la unidad NTFS estropeó los permisos. Me gustaría restaurarlos a la normalidad sin reparar manualmente todos y cada uno de los archivos.

Un problema es que de repente todos mis archivos de texto obtuvieron permisos de ejecución, lo cual es incorrecto. Entonces intenté:

sudo chmod -R a-x folder\ with\ restored\ backup/

Pero está mal, ya que también elimina el xpermiso de los directorios, lo que los hace ilegibles.

¿Cuál es el comando correcto en este caso?

gaazkam
fuente
1
Meta: nunca he entendido por qué los sistemas Unix agregan el bit de ejecución a los archivos montados desde los sistemas de archivos DOS o Windows. No es como si alguien alguna vez ejecutara esos archivos. Generalmente agrego "noexec" a mis opciones de montaje siempre que sea práctico.
Edward Falk

Respuestas:

70
chmod -R -x+X *

Las -xquita permisos de ejecución para todos
El +Xañadirán permisos de ejecución para todos, pero solamente para los directorios.

Jak Gibb
fuente
2
El comando que finalmente usé para restaurar los permisos a la normalidad: `chmod -R a-x + X, u-x + rwX, go-wx + rX directorio / nombre`
gaazkam
3
También vea la respuesta de Edward sobre la excepción para BSD
fikr4n
44
Esto falla el requisito "sin tocar carpetas". ¿Qué sucede si la ejecución (quizás para el mundo) se ha eliminado intencionalmente en algunos directorios? No deberías agregarlo.
Ben Voigt
44
Esto no funcionó en Mac. Mover el indicador -R al principio hará que esto funcione tanto en terminales Linux como en Mac. chmod -R -x+x *
JoeMoe1984
2
En realidad, con el orden correcto, se ejecuta en OSX, pero en realidad no tiene el efecto deseado. Tienes que hacerlo como dos pasos separados:chmod -R -x * && chmod -R +X *
Timmmm
14

Ok, releí las páginas de manual "chmod" para Mac OS X, BSD y Linux, e hice algunos experimentos. Esto es lo que aprendí sobre los modos simbólicos. Puede complicarse, pero vale la pena entenderlo:

  • La forma general es la cláusula [, cláusula ...] donde:
  • cláusula : = [ugoa] [+ - =] [rwxXstugo]
  • [ugoa] ( quién ) (especificar múltiples) significa establecer el permiso para usuario, grupo, otro o todos. Si no se especifica, el valor predeterminado es 'a', pero la umask está vigente.
  • [+ - =] ( acción ) (especifique uno) significa:
    • + significa agregar los permisos especificados a los permisos ya vigentes
    • - significa eliminar los permisos especificados de los permisos ya vigentes
    • = significa establecer los permisos a los permisos especificados, borrando todos los demás
  • [rwxXstugo] ( permiso ) (especifique el múltiplo de rwxXst O uno de ugo) establece los permisos para los usuarios especificados de la siguiente manera:
    • r - leer
    • w - escribir
    • x - ejecutar / buscar
    • X - ejecutar / buscar directorio iff O cualquier bit de ejecución ya estaba establecido.
    • s - suid o sgid
    • t - pegajoso
    • u - copia el permiso del usuario
    • g - copiar permiso de grupo
    • o - copiar otro permiso

Entonces, por ejemplo, a+xharía un archivo ejecutable por todos. a+Xharía que un archivo fuera ejecutable por todos SI hubiera sido ejecutable por alguien.

a+xharía que todos pudieran buscar un directorio. a+Xtambién haría que todos pudieran buscar un directorio.

La diferencia clave entre BSD y Linux es que con BSD, la determinación se realiza en función de los permisos del archivo antes de ejecutar chmod. Mientras que con Linux, la determinación se realiza inmediatamente antes de que se ejecute la cláusula + X.

Entonces, con BSD, la combinación a-x,a+Xeliminaría el permiso de ejecución / búsqueda y luego haría que todos pudieran buscar un directorio, y haría que un archivo fuera ejecutable por todos si originalmente hubiera sido ejecutable por alguien.

Con Linux, a-x,a+Xeliminaría el permiso de ejecución / búsqueda y luego haría que todos pudieran buscar un directorio, mientras que nadie dejaría un archivo ejecutable.


Aquí hay un ejemplo concreto: en una máquina BSD: un directorio, un archivo ejecutable y un archivo no ejecutable:

drwxr-x---  2 falk  staff  68 Jul 19 18:01 fee/
-rwxr-x---  1 falk  staff   0 Jul 19 18:01 fie*
-rw-r-----  1 falk  staff   0 Jul 19 18:01 foe

Observe que tanto el directorio como "fie" son ejecutables / buscables por el usuario, pero no por otros.

Ahora ejecutamos chmod a-x,a+X *. La primera cláusula eliminará el bit de ejecución / búsqueda de todos los usuarios para todos los archivos, pero la segunda cláusula lo agregará de nuevo para "tarifa" y "fie". "tarifa" porque es un directorio, y "fie" porque tenía al menos un bit ejecutable para empezar.

drwxr-x--x  2 falk  staff  68 Jul 19 18:01 fee/
-rwxr-x--x  1 falk  staff   0 Jul 19 18:01 fie*
-rw-r-----  1 falk  staff   0 Jul 19 18:01 foe

Tuve el mismo resultado al ejecutar chmod -x+X.

Conclusión: la solución de Jak Gibb funcionará en Linux, pero para BSD, necesitaría hacer dos pases.

No probé esto en SVr4 u otras variantes de Unix.

Edward Falk
fuente
Buena lectura Gracias por investigar sobre esto.
Jak Gibb
10

Una forma de hacerlo:

find backup -type f -exec chmod 0644 {} +
Satō Katsura
fuente
66
Esto podría terminar agregando o eliminando permisos que no desea cambiar. Mejor usarchmod a-x {}
Edward Falk
1
@EdwardFalk chmod a-x {}también podría terminar eliminando permisos que no desea cambiar, y podría dejar archivos que se pueden escribir en todo el mundo. El punto es que 0644 es un compromiso "generalmente razonable". El OP debería, por supuesto, también involucrar al cerebro antes de aplicar soluciones de Internet en su computadora.
Satō Katsura
44
"ax" elimina el permiso de ejecución para usuario, grupo, otro y deja los otros permisos sin cambios, hasta donde yo sé. ¿Me equivoco?
Edward Falk
1
@EdwardFalk No, tienes razón. Pero no sabe cuál es realmente el conjunto de archivos, y tampoco sabe cuáles son los permisos anteriores chmod. Si los archivos de respaldo contienen scripts y binarios, eliminarlos xes incorrecto. Si los permisos anteriores chmodson 0777 chmod a-x, los dejará 0666, que probablemente no sea lo que desea. Lo que digo es que chmod 0644es una mejor heurística, no chmod a-xestá mal.
Satō Katsura
1
@NajibIdrissi Excepto cuando, ya sabes, cambiaron a 0777 cuando los copiaste en un sistema de archivos externo que no tiene permisos UNIX. Que es exactamente lo que hizo el OP.
Satō Katsura
6
 find backup ! -type l ! -type d -exec chmod a-x {} +

Eliminaría el permiso de ejecución a los archivos que no son de tipo directorio (como solicitó) ni enlace simbólico (los enlaces simbólicos generalmente siempre son rwxrwxrwx, y chmodafectarían el objetivo del enlace simbólico en ellos).

Tenga en cuenta que:

 find backup -type f -exec chmod a-x {} +

solo cambiaría el permiso de los archivos normales . Eso excluiría directorios y enlaces simbólicos , pero también dispositivos , canalizaciones con nombre , enchufes y posiblemente otros según el sistema (aunque en el caso del OP de una copia de seguridad de un sistema de archivos NTFS, es poco probable que estén presentes).

Stéphane Chazelas
fuente
2

En zsh, use el calificador glob . para hacer coincidir solo los archivos normales (sin incluir enlaces simbólicos) y Dpara hacer coincidir los archivos de puntos:

sudo chmod a-x folder\ with\ restored\ backup/**/*(D.)

Si la línea de comando es demasiado larga, puede usar zargs:

zargs -- folder\ with\ restored\ backup/**/*(D.) -- sudo chmod a-x 
Gilles 'SO- deja de ser malvado'
fuente