Можно ли создать скрипт для сохранения и восстановления разрешений? - PullRequest
24 голосов
/ 10 августа 2010

Я использую систему Linux и мне нужно поэкспериментировать с некоторыми разрешениями для набора вложенных файлов и каталогов.Интересно, нет ли способа сохранить разрешения для файлов и каталогов, не сохраняя сами файлы.

Другими словами, я хотел бы сохранить разрешения, отредактировать некоторые файлы, настроить некоторые разрешенияи затем восстановите разрешения обратно в структуру каталогов, сохранив измененные файлы на месте.

Имеет ли это смысл?

Ответы [ 13 ]

41 голосов
/ 10 августа 2010

Самый простой способ - использовать инструменты ACL, даже если вы на самом деле не используете ACL.Просто вызовите getfacl -R . >saved-permissions для резервного копирования разрешений дерева каталогов и setfacl --restore=saved-permissions для их восстановления.

В противном случае способ резервного копирования разрешений - с помощью find -printf.(GNU найти обязательно, но это то, что у вас есть в Linux.)

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

Вы получаете файл, содержащий записи, разделенные нулевым символом;каждая запись содержит числовые разрешения, имя пользователя, имя группы и имя файла для одного файла.Для восстановления переберите записи и вызовите chmod и chown.Параметр -depth для find используется в том случае, если вы хотите сделать некоторые каталоги недоступными для записи (сначала вам нужно обработать их содержимое).

Вы можете восстановить разрешения с помощью этого фрагмента bash, полученного из фрагмента, предоставленного Даниэль Алдер :

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

Вы можете использовать следующий скрипт awk, чтобы преобразовать вывод find в некоторый код оболочки для восстановления разрешений.

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
11 голосов
/ 21 апреля 2013

Сначала установите пакет ACL:

sudo apt-get install acl

Рекурсивно Хранилище Разрешения и право собственности на файл:

getfacl -R yourDirectory > permissions.acl

Восстановление (относительно текущего пути):

setfacl --restore=permissions.acl
5 голосов
/ 10 августа 2010

гм.поэтому вам нужно: 1) прочитать права доступа к файлу 2) как-то сохранить их, связанные с каждым файлом 3) прочитать ваши сохраненные права доступа и установить их обратно

не полное решение, но некоторые идеи:

stat -c%a filename
>644

вероятно в сочетании с

find -exec

для хранения этой информации, этот вопрос имеет несколько интересных идей.в основном вы создаете временную файловую структуру, соответствующую вашим фактическим файлам, с каждым временным файлом, содержащим права доступа к файлу

, чтобы сбросить итерации по временным файлам, разрешения на чтение и вернуть текущие файлы обратно.

4 голосов
/ 17 февраля 2013

Существует также специальный инструмент для этого, который называется metastore :

metastore - это инструмент для хранения метаданных файлов / каталогов / ссылок в дереве файлов в отдельный файл и последующего сравнения и применения сохраненных метаданных к указанному дереву файлов. Я написал инструмент в качестве дополнения к git, который не хранит все метаданные, что делает его непригодным, например, для хранение / и т.д. в репо. metastore также может быть полезен, если вы хотите создать архив из дерева файлов и убедиться, что «все» (например, xattrs, mtime, owner, group) хранится вместе с файлами.

Он также доступен как Пакет Debian .

3 голосов
/ 16 июля 2015

сохранить: find . -type f |xargs ls -la| awk '{print "chmod "$1" "$NF}'>./filesPermissions.sh

восстановить: sh ./filesPermissions.sh

2 голосов
/ 03 декабря 2014

У меня есть скрипт Python для этого на https://github.com/robertknight/mandrawer/blob/master/save-file-attrs.py

save-file-attrs.py save

Сохранит права доступа, режим и время изменения файлов в дереве каталогов, укорененных в текущем рабочем каталоге, в локальный файл (.saved-file-attrs) и:

save-file-attrs.py restore

Восстановит эти атрибуты из файла и отобразит изменения.

1 голос
/ 02 октября 2015

Я нашел ответ от Дмитрия Л очень классный.Но, к сожалению, это не работает, потому что он генерирует записи вроде:

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

Чтобы избежать этого, я использую следующую команду:

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

По сути, он делает то же самое,но генерировать восьмеричные записи вроде:

chmod 644 ./.bashrc

, который работает.

1 голос
/ 10 августа 2010

вы можете получить права доступа к файлу с помощью

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

, который вернет список имен файлов и их разрешений. сохраните его где-нибудь, и, как только вы закончите, восстановите (chmod) разрешения для каждого файла.

0 голосов
/ 10 января 2019

Я заимствую этот ответ из сообщения Роймы .
Я думаю, что это должен быть лучший ответ:
Сохранить разрешения

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

Восстановление разрешений

while read PERMS OWNER GROUP FILE
do
    chmod "$PERMS" "$FILE"
    chown "${OWNER}:${GROUP}" "$FILE"
done </tmp/save-the-list
0 голосов
/ 04 марта 2018

Я нашел лучший способ (для меня) сделать это с 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()

резервная копия acl: dump_acl.py -d / path / to / dir

восстановление acl: dump_acl.py -r / path / to / dir

После выполнения сценарий создает файл acl.json в том же каталоге (с резервным копированием / восстановлением acls)

...