我正在使用Linux系统,需要在一组嵌套文件和目录上试验一些权限。我想知道是否没有办法保存文件和目录的权限,而不保存文件本身。
换句话说,我想保存权限,编辑一些文件,调整一些权限,然后将权限恢复到目录结构,保持更改的文件到位。
这有意义吗?
答案 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
您将获得一个包含由空字符分隔的记录的文件;每条记录包含一个文件的数字权限,用户名,组名和文件名。要恢复,请循环播放记录并致电chmod
和chown
。 -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