2010-08-10 203 views
19

我正在使用一个linux系统,需要在一组嵌套文件和目录上试验一些权限。我想知道是否没有办法保存文件和目录的权限,而不必自己保存文件。是否可以创建脚本来保存和恢复权限?

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

这有道理吗?

回答

4

HM。所以你需要 1)读取文件的权限 2)存储它们不知何故,与每个文件 3)读取已存储的权限,并设置回

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

stat -c%a filename 
>644 

可能结合

find -exec 

来存储这些信息,this so question有一些有趣的想法。基本上你创建一个临时文件结构符合实际的文件,包含文件的权限

重置您遍历你的临时文件,读取权限和chmod实际文件备份每个临时文件。

+0

你完美地总结了它。现在要测试这个... – NinjaCat 2010-08-10 15:29:35

1

就可以获取该文件的权限与

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

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

+3

[不要解析ls的输出](http://mywiki.wooledge.org/ParsingLs) – Gilles 2010-08-10 15:29:02

+0

我想我可以把这个和@ second的结合起来想法... – NinjaCat 2010-08-10 15:29:54

35

最简单的方法是使用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选项find是如果你想使一些目录不可写(你必须先处理他们的内容)。

您可以用贡献的Daniel Alder片段得出这个庆典片断恢复的权限:

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

您可以使用以下awk脚本打开find输出到一些shell代码来恢复权限。

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

以前从未使用ACL工具,但我也喜欢这个... – NinjaCat 2010-08-10 15:30:28

+0

小修正getfacl命令应该是:getfacl -R。 > saved-permissions – mas 2011-11-14 13:26:41

+0

这是解决方案的第二部分:恢复文件:'while IFS =:read -r -d $''0'mod用户组文件;做[-e“$ file”] ||继续; chmod -c“$ mod”“$ file”; chown -Pc“$ user”“$ file”; chgrp -Pc“$ group”“$ file”; done 2015-09-29 20:25:00

3

还为一个特殊的工具,称为metastore

metastore是要在一个文件树中的文件/目录/链接的元数据存储到一个单独的文件和工具稍后比较并将存储的元数据应用于所述文件树。我写了这个工具作为git的补充,它不存储所有元数据,因此不适用于例如。存储/等回购。如果您想创建文件树的压缩包并确保“所有内容”(例如xattrs,mtime,owner,group)与文件一起存储,那么metastore也会很有帮助。

它也可作为Debian package

+0

Metastore的已停用Git回购已在https://github.com/przemoc/metastore上的GitHub上镜像 – 2014-12-03 17:10:28

6

第一安装ACL包:

sudo apt-get install acl 

递归商店权限和所有权到文件:

getfacl -R yourDirectory > permissions.acl 

还原(相对于当前路径):

setfacl --restore=permissions.acl 
2

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

恢复:sh ./filesPermissions.sh

1

我发现从德米特罗大号非常酷的答案。但不幸的是,这是行不通的,因为它产生这样的条目:

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

为了避免它,我用下面的命令:

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

基本上,它确实是相同的,但产生八条目像:

chmod 644 ./.bashrc 

哪些工作。

+0

有人可能想引用/转义文件名,否则带空格的名称将被错误地处理 – 2016-11-08 21:17:33

0

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

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

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 

脚本执行后,将创造另一个 “recovery_acl.sh”。 替换您的域上的UTS。 像“没有这样的文件或目录”的错误意味着目录是空的。

0

我修改了Anton的命令以获取附加字符串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 
0

我发现最好的方法(对我来说)做与蟒蛇!

#!/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 /路径/到/目录

恢复ACL:dump_acl.py -R /路径/到/目录

执行后,脚本创建ACL。 json in the same dir(witch backup/restore acls)