我想将所有ZFS ACL从一个文件克隆到另一个文件。
使用POSIX ACL可以通过将getfacl的输出传递给setfacl来完成。
有没有一种简单而快速的方法来在ZFS中使用NFSv4样式的ACL? 我知道我可以读取ls -lV的输出,然后将其作为chmod一部分input,但是我似乎无法find与复制ACL的POSIX方法相当的function。
您可以使用ls -lv来代替使用ls -lv ,它可以被提供给脚本来将其转换为一系列chmod命令来复制ACL。
例如,如果AC1看起来像这样:
$ ls -lv file1 0:owner@::deny 1:owner@:read_data/write_data/append_data/write_xattr/execute /write_attributes/write_acl/write_owner:allow 2:group@:read_data/write_data/append_data:deny 3:group@:execute:allow 4:everyone@:read_data/write_data/append_data/write_xattr /write_attributes/write_acl/write_owner:deny 5:everyone@:read_xattr/execute/read_attributes/read_acl/synchronize:allow
应该将其转入以下chmod命令序列:
chmod A0=owner@::deny file2 chmod A1=owner@:read_data/write_data/append_data/write_xattr/execute/write_attributes/write_acl/write_owner:allow file2 chmod A2=group@:read_data/write_data/append_data:deny file2 chmod A3=group@:execute:allow file2 chmod A4=everyone@:read_data/write_data/append_data/write_xattr/write_attributes/write_acl/write_owner:deny file2 chmod A5=everyone@:read_xattr/execute/read_attributes/read_acl/synchronize:allow file2
我最近发现自己处在一个像上面描述的脚本一样的脚本的情况下,所以这里有一个我制作的Bash脚本(也可以作为一个函数运行到shell中)来打印必要的chmod命令列表将ZFS ACL从一个文件复制到另一个文件:
#!/斌/庆典
acl_as_chmods(){
#打印chmod命令列表,将ACL条目从“$ 1”复制到“$ 2”
[[-a“$ 1”]] 2> / dev / null || {
回声“需要有效的参考文件”。 >&2
返回1
}
ls -vd“$ 1”| {
读#第一行不是ACL信息; 旁路
读取ACL_entry
echo -n“chmod A = $ {ACL_entry#*:}”
#如果没有目标文件被指定为“$ 2”,则在运行时使用“TARGET”variables
同时读取ACL_entry || {echo“$ {2 - \ $ TARGET}”; 假; }
做
[[“$ ACL_entry”== [0-9] *:*]] && \
echo -en“$ {2 - \ $ TARGET} \ nchmod A $ {ACL_entry %%:*} + $ {ACL_entry#*:}”|| \
echo -n“$ ACL_entry”
DONE
}
}
##作为脚本或源函数运行shell?
__acl_as_chmods(){
[[“$ {FUNCNAME [1]}”==“source”]] || acl_as_chmods“$ @”
}
__acl_as_chmods“$ @”
这里有几个示例用法和它们从file1上面的输出:
〜$ ./acl_as_chmods.sh file1 file2 chmod A = owner @ :: deny file2 chmod A1 + owner @:read_data / write_data / append_data / write_xattr / execute / write_attributes / write_acl / write_owner:允许file2 chmod A2 + group @:read_data / write_data / append_data:deny file2 chmod A3 + group @:执行:允许file2 chmod A4 + everyone @:read_data / write_data / append_data / write_xattr / write_attributes / write_acl / write_owner:deny file2 chmod A5 + everyone @:read_xattr / execute / read_attributes / read_acl / synchronize:allow file2 〜$源acl_as_chmods.sh 〜$ acl_as_chmods file1 chmod A =拥有者@ :: deny $ TARGET chmod A1 + owner @:read_data / write_data / append_data / write_xattr / execute / write_attributes / write_acl / write_owner:allow $ TARGET chmod A2 + group @:read_data / write_data / append_data:deny $ TARGET chmod A3 + group @:execute:allow $ TARGET chmod A4 + everyone @:read_data / write_data / append_data / write_xattr / write_attributes / write_acl / write_owner:deny $ TARGET chmod A5 + everyone @:read_xattr / execute / read_attributes / read_acl / synchronize:allow $ TARGET
如果我们喜欢,我们甚至可以直接评估这些chmod,如果这两个文件都可以在这台主机上访问,我们希望立即将ACL从file1复制到file2 :
〜$ ls -Vd文件* #BEFORE
-rwx - x - x 1用户用户0 Jun 19 04:12 file1
店主@:--------------:------:否认
店主@:rwxp --- AW钴 - :------:允许
组@:RW-P ----------:------:拒绝
组@: - X -----------:------:允许
大家@:RW-P --- AW钴 - :------:否认
大家@: - X ---弧 - S:------:允许
--- x ------ + 1用户用户0 Jun 19 04:12 file2
店主@: - X -----------:------:允许
〜$ eval“$(acl_as_chmods file1 file2)”
〜$ ls -Vd文件* #AFTER
-rwx - x - x 1用户用户0 Jun 19 04:12 file1
店主@:--------------:------:否认
店主@:rwxp --- AW钴 - :------:允许
组@:RW-P ----------:------:拒绝
组@: - X -----------:------:允许
大家@:RW-P --- AW钴 - :------:否认
大家@: - X ---弧 - S:------:允许
-rwx - x - x 1用户用户0 Jun 19 04:12 file2
店主@:--------------:------:否认
店主@:rwxp --- AW钴 - :------:允许
组@:RW-P ----------:------:拒绝
组@: - X -----------:------:允许
大家@:RW-P --- AW钴 - :------:否认
大家@: - X ---弧 - S:------:允许
以马丁的build议和应用perl你可能会得到像这样的东西:
#!/usr/bin/perl use warnings; use strict; my $state = 0; if ($#ARGV < 1 || $#ARGV > 2) { print "\n\tUsage: $0 srcFile destFile\n"; } my $acl=`ls -lv "${ARGV[0]}"`; my @out="chmod", "arg", $ARGV[1]; foreach my $line ($acl) { chomp $line; if ($line =~ m/^\s+(\d+):(.*)$/) { if ($state > 0) { print join(" ",@out)."\n"; #system(@out) or die "system @args failed: $?"; } $state = 1; $out[1] = "A$1=$2"; } else { $line =~ m/^\s+(.*)$/; $state = 2; $out[1] .= $1; } } if ($state > 0) { print join(" ",@out)."\n"; #system(@out) or die "system @args failed: $?"; }
在取消注释系统(@out)之前尝试一下。
令人烦恼的是,这似乎并没有在贝壳级别正确曝光。 在C中,有一些函数acl_get(3SEC)和acl_set(3SEC) ,它们可以用来从一个文件中获取ACL,并将其应用到另一个(显然是其他选项)。 他们也将有用地将一个ACL从POSIX-draft转换为NFSv4types; 这是mv和cp使用的系统命令。
我曾经写过一个命令,使用这种技术将acl从源文件复制到目标文件,但是目前我找不到源代码。 我应该find它,我会附加到这个答案。