2010-08-10 3 views
19

Ich benutze ein Linux-System und muss mit einigen Berechtigungen für eine Reihe von verschachtelten Dateien und Verzeichnisse experimentieren. Ich frage mich, ob es eine Möglichkeit gibt, die Berechtigungen für die Dateien und Verzeichnisse zu speichern, ohne die Dateien selbst zu speichern.Ist es möglich, ein Skript zum Speichern und Wiederherstellen von Berechtigungen zu erstellen?

Mit anderen Worten, ich möchte die Dauerwellen speichern, einige Dateien bearbeiten, einige Berechtigungen optimieren und dann die Berechtigungen wieder in die Verzeichnisstruktur zurück, die geänderten Dateien an Ort und Stelle.

Macht das Sinn?

Antwort

4

hm. so müssen Sie 1) lesen sie Dateiberechtigungen 2) speichern irgendwie verbunden zu jeder Datei 3) Ihre gespeicherten Berechtigungen lesen und setzen sie zurück

keine vollständige Lösung, aber einige Ideen:

stat -c%a filename 
>644 

wahrscheinlich in Kombination mit

find -exec 

diese Informationen zu speichern, hat this so question einige interessante Ideen. im Grunde erstellen Sie eine temporäre Dateistruktur, die Ihren tatsächlichen Dateien entspricht, wobei jede temporäre Datei die Dateiberechtigungen enthält

um Sie zurückzusetzen, durchlaufen Sie Ihre temporären Dateien, lesen Sie Berechtigungen und chmod die tatsächlichen Dateien zurück.

+0

Sie haben es perfekt zusammengefasst. Ich werde das jetzt testen ... – NinjaCat

1

können Sie die Datei Berechtigungen mit

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

erhalten, die eine Liste von Dateinamen und ihre Berechtigungen angezeigt werden können. speichern Sie es irgendwo, und wenn Sie fertig sind - Wiederherstellen (Chmod) jeder Datei Berechtigungen.

+3

[parse nicht die Ausgabe von ls.] (http://mywiki.wooledge.org/ParsingLs) – Gilles

+0

Und ich denke, ich kann dies mit @ Sekunden kombinieren Idee ... – NinjaCat

35

Der einfachste Weg ist die Verwendung von ACL-Tools, auch wenn Sie nicht wirklich ACLs verwenden. Rufen Sie einfach getfacl -R . >saved-permissions auf, um die Berechtigungen einer Verzeichnisstruktur zu sichern, und setfacl --restore=saved-permissions, um sie wiederherzustellen.

Andernfalls ist eine Möglichkeit zum Sichern von Berechtigungen mit find -printf. (GNU finden erforderlich, aber das ist, was Sie auf Linux.)

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

Sie erhalten eine Datei Datensätze von einem Nullzeichen getrennt enthält; Jeder Datensatz enthält die numerischen Berechtigungen, den Benutzernamen, den Gruppennamen und den Dateinamen für eine Datei. Um die Daten wiederherzustellen, durchlaufen Sie die Datensätze und rufen Sie chmod und chown an. Die -depth Option zu find ist für den Fall, dass Sie einige Verzeichnisse nicht schreibbar machen möchten (Sie müssen zuerst ihren Inhalt behandeln).

Sie können die Berechtigungen mit diesem bash Ausschnitt aus einem von Daniel Alder beigetragen Schnipsel abgeleitet wiederherzustellen:

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

Sie die folgende awk-Skript verwenden, um die find Ausgabe in eine Shell-Code zu drehen, die Berechtigungen wiederherzustellen.

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

Noch nie ACL-Tools verwendet, aber ich mag das auch ... – NinjaCat

+0

Kleine Korrektur sollte der Befehl getfacl sein: getfacl -R. > saved-permissions – mas

+0

Dies ist der zweite Teil der Lösung: Wiederherstellung der Datei: 'während IFS =: read -r -d $ '\ 0' mod Benutzergruppendatei; tue [-e "$ Datei"] || fortfahren; chmod -c "$ mod" "$ datei"; chown -Pc "$ user" "$ datei"; chgrp -Pc "$ group" "$ file"; done

3

Es gibt auch ein spezielles Werkzeug für das metastore genannt:

Metastore ist ein Werkzeug, um die Metadaten von Dateien/Verzeichnisse/Links in einem Dateibaum in eine separate Datei zu speichern und zu später vergleichen und wenden Sie die gespeicherten Metadaten auf den Dateibaum an. Ich schrieb das Tool als eine Ergänzung zu Git, die nicht alle Metadaten speichert, so dass es für z. Speichern von/etc in einem Repo. metastore könnte auch hilfreich sein, wenn Sie einen Tarball einer Dateistruktur erstellen und sicherstellen möchten, dass "alles" (z. B. xattrs, mtime, Eigentümer, Gruppe) zusammen mit den Dateien gespeichert wird.

Es ist auch als Debian package verfügbar.

+0

Die verstorbene Git-Repo für Metastreet wurde auf GitHub gespiegelt auf https://github.com/przemoc/metastore –

6

das ACL-Paket zuerst installieren:

getfacl -R yourDirectory > permissions.acl 

Wiederherstellen (relativ zum Strompfad):

sudo apt-get install acl 

Recursively store Berechtigungen und den Besitz Datei

setfacl --restore=permissions.acl 
1

ich einen Python-Skript, das auf dem aktuellen Arbeitsverzeichnis in einer lokalen Datei verwurzelt in https://github.com/robertknight/mandrawer/blob/master/save-file-attrs.py

save-file-attrs.py save

speichern Wird die Berechtigungen, Modus und Änderungszeiten der Dateien im Verzeichnis-Baum zu tun (.saved -file-attrs) und:

save-file-attrs.py restore

Wird diese Attribute aus der Datei wiederherstellen und die Änderungen angezeigt werden.

2

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

wieder her:sh ./filesPermissions.sh

1

fand ich die Antwort von Dmytro L sehr cool. Aber leider ist es nicht funktioniert, weil es Einträge ist erzeugen wie:

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

es zu vermeiden, verwende ich folgenden Befehl ein:

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

Grundsätzlich tut es das gleiche, aber erzeugen Oktal Einträge wie:

chmod 644 ./.bashrc 

was funktioniert.

+0

Man könnte zitiere/Escape-Dateinamen, sonst werden Namen mit Leerzeichen falsch behandelt –

0

Hier ist ein Beispiel, um dies leicht mit einer einzigen Datei zu tun. Es sind keine zusätzlichen Tools, Skripte, temporäre Dateien usw. erforderlich. Sie können diese Methode erweitern, um bei Bedarf mit mehr Dateien zu arbeiten.In diesem speziellen Beispiel werden die Berechtigungen in einer Variablen über den Befehl stat gespeichert. Anschließend werden der Datei vorübergehend restriktive Berechtigungen entzogen. Als nächstes wird etwas damit gemacht (das aufgrund dieser vorherigen Einschränkungen möglicherweise fehlgeschlagen ist). Schließlich werden die ursprünglichen Berechtigungen wiederhergestellt.

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 

Nach der Ausführung des Skripts wird eine weitere "recovery_acl.sh" zu schaffen. Ersetzen Sie UTS in Ihrer Domain. Fehler wie "Keine solche Datei oder Verzeichnis" bedeutet, dass Verzeichnis leer ist.

0

Ich modifizierte Anton `s Befehl, um die zusätzliche Zeichenfolge chown Benutzer: Gruppe/file_or_folder_path. Jetzt können Sie ein Bash-Skript erhalten, das für jede Datei/jeden Ordner zwei Zeichenfolgen enthält.

Befehl:

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

Ausgabebeispiel:

chown root:root /file_or_folder_path 
chmod 777 /file_or_folder_path 
0

ich besten Weg (für mich) gefunden tut es mit Python!

#!/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() 

Backup acl: dump_acl.py -d/path/to/dir

Erholung acl: dump_acl.py -r/path/to/dir

Nach der Ausführung Skript acl erstellen. json im selben Verzeichnis (witch backup/restore acls)

Verwandte Themen