2010-08-10 22 views
19

Estoy usando un sistema Linux y necesito experimentar con algunos permisos en un conjunto de directorios y archivos anidados. Me pregunto si no hay alguna manera de guardar los permisos para los archivos y directorios, sin guardar los archivos ellos mismos.¿Es posible crear un script para guardar y restaurar permisos?

En otras palabras, me gustaría guardar las permanentes, editar algunos archivos, modificar algunos permisos y restaurar los permisos en la estructura del directorio, manteniendo los archivos modificados en su lugar.

¿Tiene sentido?

Respuesta

4

hm. por lo que necesita 1) leer los permisos de archivo 2) almacenarlos alguna manera, asociado a cada archivo 3) lee los permisos almacenados y los puso de vuelta

no

una solución completa, pero algunas ideas:

stat -c%a filename 
>644 

probablemente en combinación con

find -exec 

para almacenar esta información, this so question tiene algunas ideas interesantes. básicamente usted crea una estructura temporal de archivos que coincide con sus archivos reales, con cada archivo temporal que contiene los permisos de archivo

para restablecer la iteración sobre los archivos temporales, leer los permisos y modificar los archivos actuales.

+0

Lo resumió perfectamente. Voy a probar esto ahora ... – NinjaCat

1

puede obtener los permisos del archivo con

ls -l | awk '{print $1" "$NF}' 

que devolverá una lista de nombres de archivo y sus permisos. guárdelo en alguna parte, y una vez que haya terminado, restaure (chmod) los permisos de cada archivo.

+3

[No analizar la salida de ls.] (http://mywiki.wooledge.org/ParsingLs) – Gilles

+0

Y creo que puedo combinar esto con @ second's idea ... – NinjaCat

35

La manera más fácil es utilizar herramientas de ACL, incluso si no utiliza realmente ACL. Simplemente llame al getfacl -R . >saved-permissions para hacer una copia de seguridad de los permisos de un árbol de directorios y setfacl --restore=saved-permissions para restaurarlos.

De lo contrario, una forma de respaldar los permisos es con find -printf. (GNU encuentran requerido, pero eso es lo que tienes en Linux.)

find -depth -printf '%m:%u:%g:%p\0' >saved-permissions 

aparece un archivo que contiene registros separados por un carácter nulo; cada registro contiene los permisos numéricos, nombre de usuario, nombre de grupo y nombre de archivo para un archivo. Para restaurar, recorra los registros y llame al chmod y chown. La opción -depth a find es en caso de que desee que algunos directorios no sean escribibles (primero debe manejar sus contenidos).

Puede restaurar los permisos con este fragmento golpe derivado de un fragmento aportado por Daniel Alder:

while IFS=: read -r -d '' mod user group file; do 
    chown -- "$user:$group" "$file" 
    chmod "$mod" "$file" 
done <saved-permissions 

Puede utilizar la siguiente secuencia de comandos awk para convertir la salida find en algún código shell para restaurar los permisos.

find -depth -printf '%m:%u:%g:%p\0' | 
awk -v RS='\0' -F: ' 
BEGIN { 
    print "#!/bin/sh"; 
    print "set -e"; 
    q = "\047"; 
} 
{ 
    gsub(q, q q "\\" q); 
    f = $0; 
    sub(/^[^:]*:[^:]*:[^:]*:/, "", f); 
    print "chown --", q $2 ":" $3 q, q f q; 
    print "chmod", $1, q f q; 
}' > restore-permissions.sh 
+2

Nunca antes había usado herramientas ACL, pero esto también me gusta ... – NinjaCat

+0

Corrección pequeña el comando getfacl debería ser: getfacl -R. > save-permissions – mas

+0

Esta es la segunda parte de la solución: restaurar el archivo: 'while IFS =: read -r -d $ '\ 0' mod user group file; do [-e "$ file"] || continuar; chmod -c "$ mod" "$ file"; chown -Pc "$ user" "$ file"; chgrp -Pc "$ group" "$ file"; hecho

3

Existe también una herramienta especial para esa llamada metastore:

meta almacén es una herramienta para almacenar los metadatos de los archivos/directorios/enlaces en un árbol de archivos en un archivo separado y para luego compara y aplica los metadatos almacenados a dicho árbol de archivos. Escribí la herramienta como un complemento de git que no almacena todos los metadatos, por lo que no es adecuado para, p. almacenar/etc en un repositorio. metastore también podría ser útil si desea crear un archivo tar de un árbol de archivos y asegurarse de que "todo" (por ejemplo, xattrs, mtime, owner, group) se almacena junto con los archivos.

También está disponible como Debian package.

+0

El difunto Repo de Git para Metastore se ha reflejado en GitHub en https://github.com/przemoc/metastore –

6

Instala el paquete ACL primero:

sudo apt-get install acl 

recursivamente almacenar permisos y la propiedad a archivo:

getfacl -R yourDirectory > permissions.acl 

Restaurar (con relación al trayecto de la corriente):

setfacl --restore=permissions.acl 
1

que tienen una secuencia de comandos de Python para hacer esto en https://github.com/robertknight/mandrawer/blob/master/save-file-attrs.py

save-file-attrs.py save

guardará los permisos, de modo y tiempos de modificación de archivos en el árbol de directorio raíz el directorio de trabajo actual a un archivo local (.saved -FILE-attrs) y:

save-file-attrs.py restore

restaurará los atributos del archivo y mostrar los cambios.

2

Guardar:find . -type f |xargs ls -la| awk '{print "chmod "$1" "$NF}'>./filesPermissions.sh

de restauración:sh ./filesPermissions.sh

1

he encontrado la respuesta de Dmytro L muy fresco. Pero, por desgracia, es que no funciona, porque es generar entradas como:

chmod -rw-r--r-- ./.bashrc 

Para evitarlo, yo uso siguiente comando:

find . -type f | xargs stat -c "%a %n" | awk '{print "chmod "$1" "$2}' > ./filesPermissions.sh 

Básicamente, se hace lo mismo, pero generan entradas octales como:

chmod 644 ./.bashrc 

que funciona.

+0

Uno puede querer citar/escanear nombres de archivos; de lo contrario, los nombres con espacio se manejarán incorrectamente. –

0

Aquí hay un ejemplo para hacer esto fácilmente con un solo archivo. No se requieren herramientas adicionales, scripts, archivos temporales, etc. Puede ampliar este método para trabajar con más archivos si es necesario.

En este ejemplo específico, los permisos se guardan en un varibale a través del comando stat. Luego, el archivo queda temporalmente desprovisto de permisos restrictivos. Luego, se hace algo con eso (que puede haber fallado debido a esas restricciones previas). Finalmente, los permisos originales se restauran.

file=$1 
saved_permissions=$(sudo stat -c %a $file) 
sudo chmod 777 $file 
# <DO SOMETHING HERE> 
sudo chmod $saved_permissions $file 
0
#!/bin/bash 

if [ $# -ne 1 ]; then 
     echo "Enter directory"; 
     exit 0; 
fi 
# dump acls 
cd $1 
>acl 
echo "#!/bin/bash">recovery_acl.sh 
echo "cd $1">>recovery_acl.sh 
f='./' 
# create acl file sorted by dir_level 
for i in `seq 0 15`;do 
    find . -mindepth $i -maxdepth $i -type d -exec getfacl {} +|grep -E '*UTS|file:'>>acl 
done 
sed -i 's/default\:user/\-dm\ u/g' acl 
sed -i 's/default\:group/\-dm\ g/g' acl 
sed -i 's/user\:/\-m\ u\:/g' acl 
sed -i 's/group\:/\-m\ g\:/g' acl 
sed -i 's/\#\ file\:\ /\.\//g' acl 
sed -i '/^#/d' acl 

while IFS='' read -r line ; do 
    # grep dir name 
    if echo "$line" | grep -q "$f" ; then 
    dir="$line" 
    continue 
    fi 
    echo setfacl $line '"'$dir'"'>>recovery_acl.sh 
    # grep non def acl (for files) 
    if echo "$line" | grep -q '\-m' ; then 
    echo setfacl $line '"'$dir'"'/*>>recovery_acl.sh 
    fi 
done < "acl" 
rm -f acl 
sed -i 's/134/\\/g' recovery_acl.sh 
sed -i 's/040/\ /g' recovery_acl.sh 

Después de la ejecución de la escritura, será la creación de otra "recovery_acl.sh". Reemplace UTS en su dominio. Errores como "No hay tal archivo o directorio" significa que el directorio está vacío.

0

Modifiqué el comando de Anton para obtener la cadena adicional chown usuario: group/file_or_folder_path. Ahora puede obtener un script bash que contiene dos cadenas para cada archivo/carpeta.

comando:

find . -type f | xargs stat -c "%a %U:%G %n" | awk '{print "chown "$2" "$3"\nchmod "$1" "$3}' > ./filesPermissions.sh 

Ejemplo de salida:

chown root:root /file_or_folder_path 
chmod 777 /file_or_folder_path 
0

me pareció mejor manera (para mí) lo hacen con pitón!

#!/usr/bin/env python3 
# -*- coding: utf-8 -*- 
import os 
import json 
import sys 
import re 
try: 
    import posix1e 
except ImportError: 
    print("No module named 'posix1e'") 
    print("You need do: apt install python3-pylibacl") 
    sys.exit() 

def dump_acl(dir): 
    acl_dict = {} 
    for root, dirs, files in os.walk(dir): 
     try: 
      path = root.split(os.sep) 
      root_acl = str(posix1e.ACL(file=root)) 
      root_def_acl = str(posix1e.ACL(filedef=root)) 
      #print(root_acl) 
      acl_dict[root] = root_acl 
      acl_dict["default_" + root] = root_def_acl 
      for file_name in files: 
       try: 
        if 'acl.json' in file_name: 
         continue 
        file_path = root + "/" + file_name 
        file_acl = str(posix1e.ACL(file=file_path)) 
        acl_dict[file_path] = file_acl 
        #print(file_path) 
       except Exception as e: 
        print(e) 
        print(root, '/' + file_name) 
        continue 
     except Exception as e: 
      print(e) 
      print(root, '/' + file_name) 
      continue 

    with open(dir + '/acl.json', 'bw') as f: 
     f.write(json.dumps(acl_dict, ensure_ascii=False).encode('utf8')) 
    return 


def recovery_acl(dir): 
    with open(dir + '/acl.json', 'r') as f: 
     acl_dict = json.load(f) 
    try: 
     for file_path, file_acl in acl_dict.items(): 
      if file_path.startswith('default_'): 
       file_path = file_path.replace('default_', '', 1) 
       posix1e.ACL(text = file_acl).applyto(file_path, posix1e.ACL_TYPE_DEFAULT) 
       continue 
      if 'acl.json' in file_path: 
       continue 
      file_acl = file_acl.replace('\n', ',', file_acl.count('\n') -1) 
      file_acl = file_acl.replace('\134', u'\ ' [:-1]) 
      file_acl = file_acl.replace('\040', u' ') 
      if 'effective' in file_acl: 
       file_acl = file_acl.replace('\t', '') 
       f_acl = re.sub('#effective:[r,w,x,-]{3}', '', file_acl) 
      posix1e.ACL(text = file_acl).applyto(file_path) 
    except Exception as e: 
     print(e, file_path, file_acl) 
    return 

def help_usage(): 
    print("Usage:") 
    print("For dump acl: ", sys.argv[0], "-d /path/to/dir") 
    print("For restore acl:", sys.argv[0], "-r /path/to/dir") 
    print("File with acls (acl.json) storing in the same dir") 
    sys.exit() 


if len(sys.argv) == 3 and os.path.isdir(sys.argv[2]): 
    if sys.argv[1] == '-d': 
     dump_acl(sys.argv[2]) 
    elif sys.argv[1] == '-r': 
     if os.path.exists(sys.argv[2] + '/acl.json'): 
      recovery_acl(sys.argv[2]) 
     else: 
      print("File not found:", sys.argv[2] + '/acl.json') 
else: 
    help_usage() 

acl copia de seguridad: dump_acl.py -d/ruta/a/dir

acl recuperación: dump_acl.py -r/ruta/a/dir

Después de la ejecución, escritura crear ACL. json en el mismo directorio (copia de seguridad/restaurar acls)

Cuestiones relacionadas