複製或同步文件時設置所有權
以 root 身份移動或複製文件時,我經常希望根據要將文件移動到的目錄的所有者來設置這些文件的所有權。
在我開始編寫一個腳本來解析所有複製的文件的 rsync 輸出,然後在每個文件上進行這些設置 chown 之前,有沒有更好/現有的方法來做到這一點?
例如,假設我需要將文件夾複製/移動/同步到原始文件夾
tmp/ftp/new-assests/
,原始文件夾歸使用者 _www 擁有,並且我希望目標文件和包含它們的文件夾以及任何其他文件夾分別歸和擁有,並且目標目錄中有現有文件。~user1/tmp/``~user2/html-stuff/``user1``user2
是的,如果使用者具有對該文件夾的讀取權限,則他們可以自己複製文件,但這在這種情況下無關緊要。讓我們假設這些都是 nologin 使用者並且他們無權訪問源文件,如果有幫助的話。
使用
rsync
:rsync -ai --chown=user1 tmp/ftp/new-assests/ ~user1/tmp/
user1
如果允許,這會將目錄複製到給定位置,同時將文件的所有權更改為。參數的一般形式
--chown
是USER:GROUP
,但您也可以使用僅USER
將特定使用者設置為所有者,如上所述,或僅:GROUP
設置特定組(:
如果您不使用使用者 ID,則不是可選的)。
在
zsh
中,您總是可以 (asroot
) 執行以下操作:(cd tmp/ftp && tar cf - new-assests/) \ > >(USERNAME=user1; cd ~user1/tmp && tar xopf -) \ > >(USERNAME=user2; cd ~user2/html-stuff && tar xopf -)
這利用了兩個
zsh
特定的功能:
- 設置
$USERNAME
根據使用者數據庫將 shell 程序 EUID、UID、GID、EGID 和補充 gid 更改為使用者的程序(就像使用者使用該使用者名登錄一樣)。請注意,如果使用者在數據庫中不存在,則會被 忽略USERNAME=username
,但cd ~username
隨後會失敗並導致子 shell 退出。- 為輸出重定向 fd 多次(此處為 stdout,到兩個不同的程序替換)會觸發
tee
類似的行為,以將輸出發送到兩個目標(使用該mult_ios
選項啟用,預設情況下啟用)。這樣可以節省兩次閱讀原始碼。請注意,如果任何解包
tar
過程終止,則可能會中斷整個管道。
ksh
或bash
沒有更改使用者功能,但您可以使用su
orsudo
代替(如果可用),並tee
代替該multios
功能:(cd tmp/ftp && tar cf - new-assests/) | tee >(cd ~user1/tmp && sudo -u user1 tar xopf -) | (cd ~user2/html-stuff && sudo -u user2 tar xopf -)
假設目標使用者對目標目錄具有寫權限。
一些
tar
實現有一個--owner
/--group
或-chown
/-chgrp
選項來覆蓋存檔中儲存的文件的使用者名和組名。因此,另一種選擇是執行以下操作:(cd tmp/foo && tar --owner=user1 --group="$(id -g user1)" -cf - new-assets) | (cd ~user1/tmp && tar xpf -)
並重複
user2
。在其中任何一個中,您可能需要考慮如果文件具有 ACL 該怎麼辦,因為那裡沒有適合所有解決方案的尺寸。