Copie permisos a un árbol idéntico en Linux / Unix


22

Tengo un árbol de archivos con el permiso correcto. entonces tengo un árbol idéntico (filewise) (con contenido de archivo diferente resistente) con permisos incorrectos.

¿Cómo puedo transferir el diseño de permisos de un árbol a otro?

Respuestas:


8

Se puede hacer con la siguiente línea de shell:

D1=foo; D2=foo2; for entry in $(find $D1  -exec stat -f "%N:%Mp%Lp" {} \;); do $(echo $entry | sed 's#'$D1'#'$D2'#' | awk -F: '{printf ("chmod %s %s\n", $2, $1)}') ; done

simplemente configure el valor correcto para las variables D1 y D2, apúntelas a los directorios de origen y destino, ejecute y los directorios tendrán permisos sincronizados.


1
Esto supone que stat está presente. Lamentablemente, he encontrado que la estadística de comando a menudo no está presente.
Mei

@David, no sé de un sistema que carece de estadísticas. Pero es bastante trivial usar la siguiente versión "octal ls" y acomodar la solución dada en consecuencia: alias ols = "ls -la | awk '{k = 0; for (i = 0; i <= 8; i ++) k + = ((substr (\ $ 1, i + 2,1) ~ / [rwx] /) * 2 ^ (8-i)); if (k) printf (\ "% 0o \", k); print} ' "
drAlberT

Se rompe cuando cualquier ruta involucrada contiene algún tipo de carácter especial (espacios en blanco, comienza con guiones, etc.).
n.st

31

Acabo de aprender una forma nueva y sencilla de lograr esto:

getfacl -R /path/to/source > /root/perms.acl

Esto generará una lista con todos los permisos y propiedades.

Luego vaya a un nivel por encima del destino y restaure los permisos con

setfacl --restore=/root/perms.acl

La razón por la que tiene que estar un nivel por encima es que todas las rutas en perms.acl son relativas.

Debe hacerse como root.


Esta es una forma muy sencilla y sencilla de hacer copias de seguridad y restaurar permisos. Sin embargo, tenga en cuenta que getfacly setfaclno están necesariamente presentes en todos los sistemas.
the-wabbit

¿Es correcto tener .acen el primer comando y .aclen el segundo?
sfarbota

1
@sfarbota: ¡No, fue un error tipográfico! Corregido ahora. Gracias por mencionarlo.
marlar

13

Si tiene el origen y el destino, puede sincronizar sus permisos con rsync -ar --perms source/ dest

No transferirá los datos, solo permisos ...


1
no, copiará archivos si las marcas de tiempo difieren
yawniek

@yawniek The -ry --permsson redundantes, pero esto todavía sincroniza permanentes si son lo único que es diferente (que es lo que dijo en la Pregunta; si los árboles no son realmente idénticos, no debería haber dicho que lo eran).
Chris S

ok, no estaba claro entonces, quise decir que la estructura de árbol es la misma.
yawniek

12

Una cosa que podría hacer es usar el comando find para crear un script con los comandos que necesita para copiar los permisos. Aquí hay un ejemplo rápido, podría hacer mucho más con las diversas opciones de printf, que incluyen obtener el propietario, la identificación del grupo, etc.

$ find /var/log -type d -printf "chmod %m %p \n" > reset_perms
$ cat reset_perms
chmod 755 /var/log
chmod 755 /var/log/apt
chmod 750 /var/log/apache2
chmod 755 /var/log/fsck
chmod 755 /var/log/gdm
chmod 755 /var/log/cups
chmod 2750 /var/log/exim4
...

1
Sospecho que el argumento -printf para encontrar es una extensión GNU? HP-UX find no lo tiene.
Mei

1
Incluso sin la opción printf para encontrar, se puede usar la opción ls (o, en el peor de los casos, canalizar a xargs ls -l) y guardar en un archivo. Un minuto o dos de búsqueda y reemplazo, y uno tendrá un script con chmod para cada archivo.
mpez0

0

Dos caminos:

  1. Si funciona en su marca de UNIX: cp -ax / src / dest
  2. O si no, esta es la versión portátil: (cd / src && tar cpf -.) | (cd / dst && tar xpf -)

(en este último caso / dst debe existir)

Editar: lo siento, leí mal. No es lo que preguntaste.


Vale la pena mencionar que -a (para archivo) es una adición de GNU a cp, nunca lo he visto en ningún otro sistema. Es solo la abreviatura de -dpR (sin desreferencia, recursiva, preservar permisos). Las opciones R y p deben estar en cualquier versión de cp
recibirá el

0

Creo que escribiría un script en perl para hacerlo. Algo como:

#!/usr/bin/perl -nw

my $dir = $_;
my $mode = stat($dir)[2];
my $pathfix = "/some/path/to/fix/";
chmod $mode, $pathfix . $dir;

Entonces haz algo como esto:

cd /some/old/orig/path/ ; find . -type d | perlscript

Escribí esto en la parte superior de mi cabeza, y no ha sido probado; así que verifíquelo antes de dejarlo correr desenfrenado. Esto solo corrige permisos en directorios que existen; no cambiará los permisos en los archivos, ni creará directorios faltantes.


0

Se me ocurrió esto:

find $SOURCE -mindepth 1 -printf 'chmod --reference=%p\t%p\n'|sed "s/\t$SOURCE/ $DEST/g"|sh

No es totalmente a prueba de balas, pero hace lo que necesito.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.