在一个原子操作中移动文件并保留所有者和模式

在一个原子操作中移动文件并保留所有者和模式

有没有一种方法可以在一个原子操作中移动文件并保留原始所有者(组)和文件模式?那么在未设置原始所有者或模式的情况下,其他人及时访问移动的文件不会发生变化吗?

文件系统是XFS。

答案1

如果您使用相同的文件系统移动文件,那么这mv是一个原子操作。在某种程度上,该文件位于其旧位置;此后文件将位于新位置。只需一次操作即可删除旧目录中的文件条目,并将新条目添加到新目录中。该条目不仅仅是文件内容,而是整个文件索引节点,包括文件元数据,例如所有者和权限。没有任何时候可以修改权限。

如果您要将文件移动到不同的文件系统,那么该操作不是原子的:它涉及创建一个新文件,然后修改其内容和元数据直到它们与旧文件匹配,然后删除旧文件。创建的新文件始终是空的,并且属于创建它的用户。创建者可以在文件创建后立即设置传统的 Unix 权限,但不能设置访问控制列表。

mv您可以通过以所需的所有者和组身份运行并设置umask文件权限的补充来控制新文件的初始所有者、组和模式。下面是一个 Linux shell 方法,假设用户和组存在并且有一个 Bourne 风格的 shell 作为他们的登录 shell:

set $(stat -c '%U %G %a' "$original_file")
export user=$1 group=$2 mode=0$3 original_file destination
su "$user" -c 'sg "$group" -c "umask $((07777 & ~mode)) && touch "$destination" && mv -- "$original_file" "$destination"'

这非常繁琐,并且将使用正确的所有权和权限创建文件,但内容不同,时间戳不同等。如果您不希望文件在完全复制之前可见,请首先将文件移动到临时目录在仅对 root 可见的目标文件系统上,然后原子地将文件移动到位。

d=$(TMPDIR="$(dirname -- "${destination}")" mktemp -d)
chmod 700 "$d"
mv -- "$original" "$d/file"
mv -- "$d/file" "$destination"
rmdir d

答案2

现在的要求是对mv同一文件系统内的文件或文件树的操作。

这满足了原子性和所有权/组的要求。如果以root用户身份执行操作,它还将保留 setgid 和粘性位标志。对于普通文件和目录,任何用户都可以移动假如他们对源和目标父目录具有读+写+执行权限(即oldnew例中):

mv /path/to/old/source /path/to/new/destination

POSIX MVPOSIX 重命名以获得精确的细节。

答案3

有一些方法可以做到这一点;虽然不是原子的,但应该足够安全以满足您的需求。

  • 您可以使用标记复制文件-p以保留权限和所有权,然后删除原始文件:cp -p /old/path/file /new/path/ && rm -f /old/path/file

  • 您可以使用 rsync:rsync -pogXA --remove-source-files /old/path/file /new/path/

  • 如果您是根用户,您可以chmod 000移动该文件,然后恢复适当的所有者和权限。

相关内容