覆盖文件保留目标权限,无需调用 shell

覆盖文件保留目标权限,无需调用 shell

我有这种情况

$ ls -la
-rw-r--r-- 1 user user 123 Mar  5 19:32 file-a
-rwx---rwx 1 user user 987 Mar  5 19:32 file-b

我想用 覆盖file-bfile-a但我想保留 的所有权限和所有权file-b

这不起作用,因为它使用的权限file-a

cp file-a file-b # << edit: this works as expected! My fault!
mv file-a file-b

这可行,但只能从 shell 调用。想象一下我只能调用或类似函数的情况execve

cat file-a > file-b

我知道,我可以执行类似的事情

sh -c "cat file-a > file-b"

但这会给转义文件名带来困难,所以我不想使用它。

是否有一些常用命令可以执行此操作,或者我应该编写自己的帮助程序 C 程序来完成此任务?

答案1

复制文件而不复制模式的简单命令是

dd if=file-a of=file-b

但随后您会收到dd写入 stderr 的详细状态消息。您可以通过在 shell 中运行该命令并添加 来抑制这种情况2> /dev/null,但随后您又回到了第 1 步。如果您有 GNU dd,您可以这样做

dd if=file-a of=file-b status=none

答案2

rsync --inplace file-a file-b应该做你想做的事。

https://linux.die.net/man/1/rsync

--inplace 此选项更改 rsync 在需要更新文件数据时传输文件的方式:rsync 不是创建文件的新副本并在完成后将其移动到位的默认方法,而是直接写入更新的数据到目标文件。

答案3

man cp说:

对于每个已存在的目标文件,如果权限允许,其内容将被覆盖。除非-p指定了该选项,否则其模式、用户 ID 和组 ID 不会更改。

如果您设置-p,则将cp尝试保留源文件的所有权和访问权限,但默认行为是尽可能保留目标文件的这些属性。

什么意思“如果可能的话“?

好吧,如果目标文件不存在,当然不可能,在这种情况下cp将创建一个具有默认所有权(当前用户和当前用户的默认组)和默认权限的文件(另请参阅man 2 umask)。它不会-p自行恢复行为。

此外,如果当前用户无法打开目标进行写入,则cp无法以这种方式工作。在这种情况下,cp要么会失败,要么如果您指定了-f,它将回退到删除现有文件(因此只需要对其目录的写访问权限),然后再次应用第一种情况。

mv不适合您的种姓的原因是因为总是首先尝试使用( )mv以原子方式移动文件,这仅在目标不存在且源和目标位于同一存储实体上时才有效(通常这意味着相同)分割)。其优点是它确实被视为单个原子操作,使文件在一个位置消失并重新出现在另一个位置,并保留所有所有权和文件权限。如果这是不可能的,据记录其工作原理与renameman 2 renamerenamemv

rm -f destination_path && \
cp -pRP source_file destination && \
rm -rf source_file

相关内容