Answers:
不用mv
重定向,只需重定向即可cat
。例如:
TMP=$(mktemp)
modifyfile "$original" "$TMP"
cat "$TMP" > "$original"
这将覆盖$original
的内容$TMP
,而不会在文件级别触及任何内容。
rm "$TMP"
做,但是它似乎可以满足我的要求。
mv
。我没有解决该问题的方法。
chown
仅作为根用户。chmod
并且chgrp
可能会或可能不会起作用,具体取决于用户的权限。都不复制其他属性,例如ACL或特定于文件系统的扩展属性。
有两种策略可以用新版本替换文件:
使用新版本创建一个临时文件,然后将其移动到位。
覆盖旧文件。
如果可以,请使用方法1,但首先使用来复制原始文件的属性cp -p --attributes-only
。这需要GNU coreutils(即非嵌入式Linux或足够类似于Linux的环境)。如果您cp
没有--attributes-only
,请忽略此选项:它可以工作,但也会复制数据。
tmp=$(mktemp)
cp -p --attributes-only "$original" "$tmp"
modifyfile "$original" "$tmp"
mv -f "$tmp" "$original"
如果您不能复制现有文件的属性,例如,因为您具有对该文件的写权限但不拥有该文件,并且想要保留所有者,则只能使用方法2。为了最大程度地减少数据丢失的风险:
tmp=$(mktemp)
backup="${original}~"
modifyfile "$original" "$tmp"
cp -p "$original" "$backup"
cp -f "$tmp" "$original"
cp -p --attributes-only "$original" "$tmp"
cp
实现仍然没有这种东西。
在讨论了第一个答案之后,我提出了一个不同的答案:
TMP="$(mktemp "$original".XXXXXXXXXX)"
modifyfile "$original" "$TMP"
chmod --reference="$original" "$TMP"
chown --reference="$original" "$TMP"
mv -f "$TMP" "$original"
备注:
$original
在mktemp
模板中使用以确保临时文件未放置在,/tmp
而是位于$original
。我相信,如果/tmp
将其安装在其他文件系统上,则该操作将不再是原子的。mktemp
如果包含空格,则现在引用的结果。$()
代替``,因为我认为它更干净。ch{mod,own} --reference
用于将的权限转移$original
到$TMP
。如果有人有其他想法,可以并且应该传输什么元数据,请编辑我的帖子并添加。