Is it possible to create a script to save and rest

2020-05-11 11:34发布

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 the files and directories, without saving the files themselves.

In other words, I'd like to save the perms, edit some files, tweak some permissions, and then restore the permissions back onto the directory structure, keeping the changed files in place.

Does that make sense?

13条回答
smile是对你的礼貌
2楼-- · 2020-05-11 12:27

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.

查看更多
在下西门庆
3楼-- · 2020-05-11 12:27

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)

查看更多
贪生不怕死
4楼-- · 2020-05-11 12:33

Install the ACL package first:

sudo apt-get install acl

Recursively store permissions and ownership to file:

getfacl -R yourDirectory > permissions.acl

Restore (relative to current path):

setfacl --restore=permissions.acl
查看更多
太酷不给撩
5楼-- · 2020-05-11 12:33

I modified Anton`s command to get the additional string chown user:group /file_or_folder_path. Now you can get a bash script which contains two string for each file/folder.

command:

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

Example of output:

chown root:root /file_or_folder_path
chmod 777 /file_or_folder_path
查看更多
萌系小妹纸
6楼-- · 2020-05-11 12:36

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
查看更多
做个烂人
7楼-- · 2020-05-11 12:38

I found the answer from Dmytro L very cool. But, unfortunately, it's doesn't work, because it's generate entries like:

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

To avoid it, I use following command:

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

Basically, it does the same, but generate octal entries like:

chmod 644 ./.bashrc

which works.

查看更多
登录 后发表回答