是否可以创建一个脚本来保存和恢复权限?

时间:2010-08-10 14:51:02

标签: linux permissions shell unix

我正在使用Linux系统,需要在一组嵌套文件和目录上试验一些权限。我想知道是否没有办法保存文件和目录的权限,而不保存文件本身。

换句话说,我想保存权限,编辑一些文件,调整一些权限,然后将权限恢复到目录结构,保持更改的文件到位。

这有意义吗?

13 个答案:

答案 0 :(得分:41)

最简单的方法是使用ACL工具,即使您实际上并未使用ACL。只需致电getfacl -R . >saved-permissions即可备份目录树的权限,并setfacl --restore=saved-permissions进行恢复。

否则,备份权限的方法是使用find -printf。 (GNU需要找到,但这就是你在Linux上所拥有的。)

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

您将获得一个包含由空字符分隔的记录的文件;每条记录包含一个文件的数字权限,用户名,组名和文件名。要恢复,请循环播放记录并致电chmodchown-depth的{​​{1}}选项是为了防止某些目录无法写入(您必须先处理其内容)。

您可以使用从Daniel Alder提供的代码段派生的此bash代码段恢复权限:

find

您可以使用以下awk脚本将while IFS=: read -r -d '' mod user group file; do chown -- "$user:$group" "$file" chmod "$mod" "$file" done <saved-permissions 输出转换为某些shell代码以恢复权限。

find

答案 1 :(得分:11)

首先安装ACL包:

sudo apt-get install acl

递归存储权限和所有权到文件:

getfacl -R yourDirectory > permissions.acl

恢复(相对于当前路径):

setfacl --restore=permissions.acl

答案 2 :(得分:5)

HM。所以你需要 1)读取文件权限 2)以某种方式存储它们,与每个文件相关联 3)读取您存储的权限并将其重新设置

不是一个完整的解决方案,而是一些想法:

stat -c%a filename
>644

可能与

结合使用
find -exec

存储此信息,this so question有一些有趣的想法。基本上,您创建一个与您的实际文件匹配的临时文件结构,每个临时文件包含文件权限

重置你的temp文件,读取权限并重新调整实际文件。

答案 3 :(得分:4)

还有一个名为metastore的特殊工具:

  

Metastore 是一种工具,用于将文件树中的文件/目录/链接的元数据存储到单独的文件中,以便稍后比较并将存储的元数据应用于所述文件树。我将该工具编写为git的补充,它不存储所有元数据,因此不适用于例如在回购中存储/ etc。如果要创建文件树的tarball并确保“一切”(例如xattrs,mtime,owner,group)与文件一起存储,则metastast也会有所帮助。

它也可以Debian package

答案 4 :(得分:3)

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

恢复 sh ./filesPermissions.sh

答案 5 :(得分:2)

我有一个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

将从文件中恢复这些属性并显示更改。

答案 6 :(得分:1)

您可以使用

获取文件的权限
ls -l | awk '{print $1" "$NF}'

将返回文件名及其权限列表。 将它保存到某个地方,一旦完成 - 恢复(chmod)每个文件的权限。

答案 7 :(得分:1)

我发现Dmytro L的答案非常酷。但是,不幸的是,它不起作用,因为它生成如下条目:

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

为避免这种情况,我使用以下命令:

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

基本上,它也是这样,但生成八进制条目,如:

chmod 644 ./.bashrc

有效。

答案 8 :(得分:0)

以下是使用单个文件轻松完成此操作的示例。不需要其他工具,脚本,临时文件等。如果需要,您可以扩展此方法以处理更多文件。

在此特定示例中,权限通过stat命令保存在varibale中。然后,该文件暂时被剥夺任何限制性权限。接下来,完成了一些事情(由于这些先前的限制,可能已经失败)。最后,恢复原始权限。

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

答案 9 :(得分: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

执行脚本后,将创建另一个&#34; recovery_acl.sh&#34;。 替换您域中的UTS。 错误如&#34;没有这样的文件或目录&#34;意思是dir是空的。

答案 10 :(得分:0)

我修改了Anton`s命令以获取附加字符串 chown user:group / file_or_folder_path 。现在你可以得到一个bash脚本,其中包含每个文件/文件夹的两个字符串。

命令:

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

输出示例:

chown root:root /file_or_folder_path
chmod 777 /file_or_folder_path

答案 11 :(得分:0)

我找到了最好的方法(对我来说)用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)

答案 12 :(得分:0)

我从roaima's post借用了这个答案。
我认为这应该是最好的答案:
保存权限

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