Is it possible to create a script to save and restore permissions?

前端 未结 13 1325
逝去的感伤
逝去的感伤 2021-01-30 04:29

I am using a linux system and need to experiment with some permissions on a set of nested files and directories. I wonder if there is not some way to save the permissions for t

相关标签:
13条回答
  • 2021-01-30 05:12

    The easiest way is to use ACL tools, even if you don't actually use ACLs. Simply call getfacl -R . >saved-permissions to back up the permissions of a directory tree and setfacl --restore=saved-permissions to restore them.

    Otherwise, a way to back up permissions is with find -printf. (GNU find required, but that's what you have on Linux.)

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

    You get a file containing records separated by a null character; each record contains the numeric permissions, user name, group name and file name for one file. To restore, loop over the records and call chmod and chown. The -depth option to find is in case you want to make some directories unwritable (you have to handle their contents first).

    You can restore the permissions with this bash snippet derived from a snippet contributed by Daniel Alder:

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

    You can use the following awk script to turn the find output into some shell code to restore the permissions.

    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
    
    0 讨论(0)
  • 2021-01-30 05:13

    hm. so you need to 1) read file permissions 2) store them somehow, associated to each file 3) read your stored permissions and set them back

    not a complete solution but some ideas:

    stat -c%a filename
    >644
    

    probably in combination with

    find -exec
    

    to store this information, this so question has some interesting ideas. basically you create a temporary file structure matching your actual files, with each temp file containing the file permissions

    to reset you iterate over your temp files, read permissions and chmod the actual files back.

    0 讨论(0)
  • 2021-01-30 05:13

    I found best way (for me) do it with 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

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

    After execution, script create acl.json in the same dir(witch backup/restore acls)

    0 讨论(0)
  • 2021-01-30 05:15

    I have a Python script for doing this at https://github.com/robertknight/mandrawer/blob/master/save-file-attrs.py

    save-file-attrs.py save

    Will save the permissions, mode and modification times of files in the dir tree rooted at the current working directory to a local file (.saved-file-attrs) and:

    save-file-attrs.py restore

    Will restore those attributes from the file and display the changes.

    0 讨论(0)
  • 2021-01-30 05:15

    I borrow this answer from roaima's post.
    I think this should be the best answer:
    Save the permissions

    find * -depth -exec stat --format '%a %u %g %n' {} + >/tmp/save-the-list
    

    Restore the permissions

    while read PERMS OWNER GROUP FILE
    do
        chmod "$PERMS" "$FILE"
        chown "${OWNER}:${GROUP}" "$FILE"
    done </tmp/save-the-list
    
    0 讨论(0)
  • 2021-01-30 05:21

    There is also a special tool for that called metastore:

    metastore is a tool to store the metadata of files/directories/links in a file tree to a separate file and to later compare and apply the stored metadata to said file tree. I wrote the tool as a supplement to git which does not store all metadata, making it unsuitable for e.g. storing /etc in a repo. metastore could also be helpful if you want to create a tarball of a file tree and make sure that "everything" (e.g. xattrs, mtime, owner, group) is stored along with the files.

    It's also available as Debian package.

    0 讨论(0)
提交回复
热议问题