我有这种情况
$ 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-b
,file-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
以原子方式移动文件,这仅在目标不存在且源和目标位于同一存储实体上时才有效(通常这意味着相同)分割)。其优点是它确实被视为单个原子操作,使文件在一个位置消失并重新出现在另一个位置,并保留所有所有权和文件权限。如果这是不可能的,据记录其工作原理与rename
man 2 rename
rename
mv
rm -f destination_path && \ cp -pRP source_file destination && \ rm -rf source_file