复制或同步文件时设置所有权

复制或同步文件时设置所有权

当以 root 身份移动或复制文件时,我经常希望根据要将文件移动到的目录的所有者来设置这些文件的所有权。

在我开始编写一个脚本来解析所有复制的文件的 rsync 输出,然后对每个文件进行 chown 设置之前,是否有更好/现有的方法来执行此操作?

举个例子,假设我需要将文件夹复制/移动/同步tmp/ftp/new-assests/到原始文件夹由用户 _www 拥有~user1/tmp/,并且我希望目标文件和包含它们的文件夹以及任何其他文件夹分别由和~user2/html-stuff/拥有,目标目录中有现有文件。user1user2

是的,如果用户具有该文件夹的读取权限,他们可以自己复制文件,但这在本例中是无关紧要的。让我们假设这些都是 nologin 用户,他们无权访问源文件(如果有帮助的话)。

答案1

使用rsync

rsync -ai --chown=user1 tmp/ftp/new-assests/ ~user1/tmp/

user1如果允许,这会将目录复制到给定位置,同时将文件的所有权更改为。

参数的一般形式--chownUSER:GROUP,但您也可以仅用于USER将特定用户设置为所有者,如上所述,或者仅:GROUP用于设置特定组(:如果您省略用户 ID,则该参数不是可选的)。

答案2

在 中zsh,你总是可以做 (as root) 类似的事情:

(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 更改为用户的 EUID(就像用户使用该用户名登录一样)。请注意,如果数据库中不存在该用户,则会被 静默忽略USERNAME=username,但cd ~username随后会失败并导致子 shell 退出。
  • 多次重定向 fd 进行输出(这里是 stdout,到两个不同的进程替换)会触发tee类似的行为,将输出发送到两个目标(使用该mult_ios选项启用,默认情况下启用)。这样就可以节省两次阅读源代码的时间。

请注意,如果任何解包tar进程终止,则可能会中断整个管道。

ksh或者bash没有更改用户功能,但您可以使用suorsudo代替(如果可用),并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 该怎么办,因为没有一种适合所有解决方案。

相关内容