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

lbu*_*tlr 6 permissions rsync file-copy amazon-ec2

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

在我开始编写一个脚本来解析所有被复制的文件的 rsync 输出然后通过每个文件上的那些设置 chown 之前,有没有更好的/现有的方法来做到这一点?

作为一个例子,说我需要的文件夹同步复制/移动/tmp/ftp/new-assests/~user1/tmp/~user2/html-stuff/原稿由用户_www拥有和我想要的目标文件,并且包含它们的文件夹和任何其他文件夹为所拥有的user1,并user2分别与目标目录中有现有文件。

是的,如果用户具有对该文件夹的读取访问权限,则他们可以自己复制文件,但这在这种情况下无关紧要。让我们假设这些都是 nologin 用户并且他们无权访问源文件,如果有帮助的话。

Sté*_*las 5

在 中zsh,您始终可以(作为root)执行以下操作:

(cd tmp/ftp && tar cf - new-assests/) \
   > >(USERNAME=user1; cd ~user1/tmp && tar xopf -) \
   > >(USERNAME=user2; cd ~user2/html-stuff && tar xopf -)
Run Code Online (Sandbox Code Playgroud)

这利用了两个zsh特定的功能:

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

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

kshbash没有更改用户功能,但您可以使用susudo代替(如果可用),并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 -)
Run Code Online (Sandbox Code Playgroud)

这假设目标用户对目标目录具有写权限。

某些tar实现具有--owner/--group-chown/-chgrp选项来覆盖存储在存档中的文件的用户名和组名。因此,另一种选择是执行以下操作:

(cd tmp/foo && tar --owner=user1 --group="$(id -g user1)" -cf - new-assets) |
  (cd ~user1/tmp && tar xpf -)
Run Code Online (Sandbox Code Playgroud)

并重复user2

在其中任何一个中,您可能需要考虑如果文件具有 ACL 该怎么办,因为那里没有适合所有解决方案的尺寸。


Kus*_*nda 5

使用rsync

rsync -ai --chown=user1 tmp/ftp/new-assests/ ~user1/tmp/
Run Code Online (Sandbox Code Playgroud)

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

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

  • `--chown="user1:$(id -g user1)"` 如果您还想将 gid 更改为用户的主要组的 gid。 (2认同)