有没有一种方法可以在一个原子操作中移动文件并保留原始所有者(组)和文件模式?那么在未设置原始所有者或模式的情况下,其他人及时访问移动的文件不会发生变化吗?
文件系统是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
答案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
移动该文件,然后恢复适当的所有者和权限。