我想將所有 ZFS ACL 從一個檔案克隆到另一個檔案。
對於 POSIX ACL,這可以透過管道輸出getfacl
to來完成setfacl
。
是否有一種簡單快速的方法可以使用 ZFS 中的 NFSv4 樣式 ACL 來執行此操作?我知道我可以讀取 的輸出ls -lV
,然後將其作為 a 的一部分輸入chmod
,但我似乎找不到與複製 ACL 的 POSIX 方式等效的功能。
答案1
ls -lV
您可以使用which來代替使用ls -lv
,它可以輸入到腳本中,將其轉換為一系列chmod
命令來複製 ACL。
例如,如果 ACl 看起來像這樣:
$ 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從一個文件複製到另一個文件:
#!/bin/bash acl_as_chmods () { # 列印 chmod 指令列表,將 ACL 條目從“$1”複製到“$2” [[ -a "$1" ]] 2>/dev/null || { echo“需要有效的參考文件。” >&2 返回1 } ls -vd“$1”| { read #第一行不是ACL訊息;旁路 讀取 ACL_entry echo -n "chmod A=${ACL_entry#*:}" # 如果沒有將目標檔案指定為“$2”,則在執行時使用“TARGET”變量 讀取 ACL_entry || 時{ echo " ${2-\$TARGET}";錯誤的; } 做 [[ "$ACL_entry" == [0-9]*:* ]] && \ echo -en " ${2-\$TARGET}\nchmod A${ACL_entry%%:*}+${ACL_entry#*:}" || \ 回顯-n“$ACL_entry” 完畢 } } ## 作為腳本或來源函數運行到 shell? __acl_as_chmods () { [[ "${FUNCNAME[1]}" == 「源" ]] || acl_as_chmods“$@” } __acl_as_chmods“$@”
以下是幾個範例用法及其輸出文件1從上面:
~$ ./acl_as_chmods.sh 檔案 1 檔案 2 chmod A=所有者@::拒絕檔案2 chmod A1+owner@:read_data/write_data/append_data/write_xattr/execute/write_attributes/write_acl/write_owner:允許檔案2 chmod A2+group@:read_data/write_data/append_data:拒絕 file2 chmod A3+group@:執行:允許檔案2 chmod A4+everyone@:read_data/write_data/append_data/write_xattr/write_attributes/write_acl/write_owner:拒絕檔案2 chmod A5+everyone@:read_xattr/execute/read_attributes/read_acl/synchronize:允許 file2 ~$ 源 acl_as_chmods.sh ~$ acl_as_chmods file1 chmod A=所有者@::拒絕$TARGET chmod A1+owner@:read_data/write_data/append_data/write_xattr/execute/write_attributes/write_acl/write_owner:允許$TARGET chmod A2+group@:read_data/write_data/append_data:拒絕$TARGET chmod A3+group@:執行:允許$TARGET chmod A4+everyone@:read_data/write_data/append_data/write_xattr/write_attributes/write_acl/write_owner:拒絕$TARGET chmod A5+everyone@:read_xattr/execute/read_attributes/read_acl/synchronize:允許$TARGET
如果我們願意,我們甚至可以直接評估這些 chmod,如果這兩個檔案都可以在此主機上存取並且我們希望從中複製 ACL文件1到文件2立即地:
~$ ls -Vd 檔案* #之前 -rwx--x--x 1 個使用者 user 0 Jun 19 04:12 file1 所有者@:--------------:------:拒絕 所有者@:rwxp---AW-Co-:------:允許 組@:rw-p----------:------:拒絕 組@:--x----------:------:允許 大家@:rw-p---AW-Co-:-------:否認 大家@:--x---aRc--s:------:允許 ---x------+ 1 用戶 用戶 0 六月 19 04:12 file2 所有者@:--x----------:------:允許 ~$ eval "$(acl_as_chmods file1 file2)" ~$ ls -Vd 檔案* #之後 -rwx--x--x 1 個使用者 user 0 Jun 19 04:12 file1 所有者@:--------------:------:拒絕 所有者@:rwxp---AW-Co-:------:允許 組@:rw-p----------:------:拒絕 組@:--x----------:------:允許 大家@:rw-p---AW-Co-:-------:否認 大家@:--x---aRc--s:------:允許 -rwx--x--x 1 個使用者 user 0 Jun 19 04:12 file2 所有者@:--------------:------:拒絕 所有者@:rwxp---AW-Co-:------:允許 組@:rw-p----------:------:拒絕 組@:--x----------:------:允許 大家@:rw-p---AW-Co-:-------:否認 大家@:--x---aRc--s:------:允許
答案2
答案3
服用什麼馬丁建議並應用一些 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: $?";
}
在取消註解 system(@out) 行之前嘗試一下。
答案4
令人煩惱的是,這似乎沒有在 shell 層級正確暴露。在 C 中,有一些函數acl_get(3SEC)
和acl_set(3SEC)
可用於從一個檔案中取得 ACL 並將其套用到另一個檔案(顯然還有其他選項)。他們也可以有效地將 ACL 從 POSIX 草稿轉換為 NFSv4 類型;這就是系統指令喜歡mv
和cp
使用的。
我曾經編寫過一個命令,使用這種技術將 acl 從原始文件複製到目標文件,但我目前找不到原始程式碼。如果我找到它,我會將其附加到這個答案中。