Necesita corregir los permisos de archivo en el directorio de inicio de un usuario

24

¿Alguien tiene una herramienta o script que corrija recursivamente los permisos de archivo en un directorio?

En una máquina Ubuntu Linux, se copiaron un montón de archivos en un disco USB con permisos completos de 777 (usuario, grupo, otro: lectura, escritura, ejecución) por error. Quiero volver a ponerlos en el directorio del usuario corregido.

Los directorios deben ser 775 y todos los demás archivos pueden ser 664. Todos los archivos son imágenes, documentos o MP3, por lo que ninguno de ellos debe ser ejecutable. Si el bit de directorio está configurado, entonces necesita ejecución, de lo contrario solo necesita usuario y grupo, lectura y escritura.

Pensé que valía la pena comprobar si existe tal utilidad antes de hackear un script de shell :)

mlambie
fuente

Respuestas:

51

Esto debería funcionar:

find /home/user -type d -print0 | xargs -0 chmod 0775
find /home/user -type f -print0 | xargs -0 chmod 0664
freiheit
fuente
1
+1 por usar -print0 / xargs -0 :-).
sleske 01 de
14

find puede hacer el truco solo con -exec:

find /home/user -type f -exec chmod 0664 {} \;
find /home/user -type d -exec chmod 0775 {} \;

para evitar que find genere un chmod para cada entrada:

find /home/user -type f -exec chmod 0664 {} +
find /home/user -type d -exec chmod 0775 {} +

(esto efectivamente llama a chmod una vez con la lista de todos los archivos como parámetros en lugar de un chmod por archivo)

ThorstenS
fuente
66
Más lento que usar xargs, ya que está bifurcando un chmod para cada archivo, donde xargs ejecutará un proceso chmod con tantos archivos como pueda caber en una línea de comando. En un árbol muy grande, esto puede marcar una gran diferencia.
David Pashley el
1
Además, print0 / xargs -0 manejará incluso nombres de archivo muy extraños; no estoy tan seguro de encontrar -exec.
sleske 01 de
8

Esta respuesta no resolverá su problema, pero alguien podría encontrarlo útil para un problema similar en el que los archivos tienen menos permiso del que deberían.

# chmod -R . u=rwX,g=rX,o=rX

La magia es el permiso X, en lugar de x. La página de manual de chmod lo describe así:

ejecutar / buscar solo si el archivo es un directorio o ya tiene permiso de ejecución para algún usuario

Esto no es adecuado en su caso, ya que sus archivos tienen permiso de ejecución, por lo que coincidirá con la segunda prueba.

David Pashley
fuente
1
g debería ser rwX para 775 y 664.
aventurina el
1

Hice un script con la solución de freiheit, agrega comprobación básica de argumentos.

#!/bin/sh

if [ $# -lt 1 ]; then
    echo "USAGE: $0 <path>"
    exit 1
fi

find $1 -type d -print0 | xargs -0 chmod 0755
find $1 -type f -print0 | xargs -0 chmod 0644
Marcos
fuente
Buena idea. Sin embargo, la segunda línea genera un error cuando el destino es un directorio: chmod: missing operand after ‘0644’. ¿Puedo sugerir envolver las declaraciones de búsqueda con una comprobación para ver si existe el objetivo? if [ -d $1 ]; then find $1 -type d -print0 | xargs -0 chmod 0755; fi; if [ -f $1 ]; then find $1 -type f -print0 | xargs -0 chmod 0644; fi
Inverso
Es casi correcto; pero si el destino es un directorio, olvidó modificar los archivos que contiene, y si es un archivo, solo necesita modificar ese archivo únicamente.
Sean
0

En caso de que esté usando ssh, es una buena idea no modificar los ~/.sshpermisos.

DIR=/home/user
find $DIR -type d -not -path "$DIR/.ssh" -print0 | xargs -0 chmod 0775
find $DIR -type f -not -path "$DIR/.ssh/*" -print0 | xargs -0 chmod 0664
Tombart
fuente
0

El otro día hice un script bash realmente simple porque necesitaba arreglar los permisos. ¿Por qué no hay una utilidad formal para restablecer los permisos básicos, no root, de archivos y carpetas?

El script usa find para 755 todas las carpetas y 644 bibliotecas. Luego prueba cada archivo con readelf para ver si tiene un encabezado binario elf. Si no, escanea los dos primeros caracteres en busca de shebang #!. Es 755 esas instancias y 644 todo lo demás después de comprobar si el archivo ya tiene el permiso correspondiente.

Los casos especiales se manejan con una excepción como los *.bakarchivos que se ignorarán.

#!/bin/bash
read -r -p "Correct file and folder permissions? [y/N] " chse
if [[ "$chse" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
  echo "Processing ..."
  find -H $(pwd) -type d -exec chmod 0755 {} \;
  # set dirs to 755
  find -H $(pwd) -type f \( -iname '*.so.*' -o -iname '*.so' \) -exec chmod 0644 {} \;
  # libs
  IFS=$'\n'
  for value in $(find -H $(pwd) -type f ! \( -iname '*.so.*' -o -iname '*.so' -o -iname '*.bak' \) -printf '%p\n'); do
    tstbin=$(readelf -l "$value" 2>/dev/null | grep -Pio 'executable|shared')
    if [ -z "$tstbin" ]; then
      tstbat=$(cat "$value" | head -c2 | grep -io '#!')
      if [ -n "$tstbat" ]; then
        perm=$(stat -c '%a' "$value")
        if [ "$perm" != "755" ]; then
          chmod 755 $value
          echo "Set script  755 $value"
          # set batch to 755
        fi
      else
        perm=$(stat -c '%a' "$value")
        if [ "$perm" != "644" ]; then
          chmod 644 $value
          echo "Set regular 644 $value"
          # set regular files to 644
        fi
      fi
      # above aren't elf binary
    else
      perm=$(stat -c '%a' "$value")
      if [ "$perm" != "755" ]; then
        chmod 755 $value
        echo "Set binary  755 $value"
        # set elf binaries to 755
      fi
    fi
  done
  unset IFS
  # process linux permissions for files and folders
else
  echo "Aborted."
fi
noabody
fuente
0

Encontré una solución simplificada de C-shell. Esto podría no ser completamente infalible, pero debería funcionar para la mayoría de los directorios. Asume que el comando 'archivo' de Unix funciona y encuentra archivos exec para restablecerlos a los permisos de ejecución:

find /home/user -type d | xargs chmod 0775
find /home/user -type f | xargs -0 chmod 0664
find /home/user -type f -exec file {} \; | grep executable | cut -d":" -f1 | xargs chmod 0775
K. Donovan
fuente
1
Esto no solo repite algunas de las respuestas, sino que introduce un error y una funcionalidad que el OP no solicitó.
RalfFriedl
0

Una alternativa, que no responde exactamente a la solicitud original, pero es más probable lo que pretende el OP, es especificar los permisos simbólicamente. Por ejemplo, supongo que OP quiere "eliminar el acceso de escritura para el público y eliminar el permiso ejecutable de todos los archivos".

Esto es posible si utiliza la representación de permiso simbólico.

  • ow es "eliminar el acceso de escritura del público" ("o" - otros, "-" - eliminar, "w" - escribir)
  • ax es "eliminar ejecutar para todos en archivos solamente" ("a" - todos, "-" - eliminar, "x" - ejecutar)

Al escribirlo de esta manera, en lugar de configurar explícitamente "0664", evita accidentalmente permitir permisos adicionales a los archivos que anteriormente estaban bloqueados. Por ejemplo, si un archivo era 0770, no se convertirá en 0664 por error.

Para hacer el primer requisito, puede usar chmod:

chmod --recursive o-w $dir

Para hacer el segundo requisito:

find $dir -type f -exec chmod a-x {} +

O para hacer ambas cosas:

find $dir -type f -exec chmod a-x,o-w {} +
find $dir -type d -exec chmod o-w {} +
chutz
fuente