Linux 用自身覆盖文件的最佳方法
读取文件然后将内容写入同一文件的最快/最优雅的方式是什么 在Linux上,这并不总是与“触摸”文件相同,例如,如果文件代表某个硬件设备Linux 用自身覆盖文件的最佳方法,linux,bash,shell,Linux,Bash,Shell,读取文件然后将内容写入同一文件的最快/最优雅的方式是什么 在Linux上,这并不总是与“触摸”文件相同,例如,如果文件代表某个硬件设备 对我有效的一种可能性是echo$(cat$file)>$file,但我想知道这是否是最佳做法。通常不能一步完成,因为写入文件会干扰读取。如果您在常规文件上尝试此操作,则重定向可能会在读取任何内容之前将文件清空 你最保险的办法是把它分成两步。如果需要,可以将其隐藏在函数调用后面 rewrite() { local file=$1 local co
对我有效的一种可能性是
echo$(cat$file)>$file
,但我想知道这是否是最佳做法。通常不能一步完成,因为写入文件会干扰读取。如果您在常规文件上尝试此操作,则
重定向可能会在读取任何内容之前将文件清空
你最保险的办法是把它分成两步。如果需要,可以将其隐藏在函数调用后面
rewrite() {
local file=$1
local contents=$(< "$file")
cat <<< "$contents" > "$file"
}
...
rewrite /sys/misc/whatever
rewrite(){
本地文件=$1
本地内容=$(<“$文件”)
cat中的海绵实用程序允许此操作
~$ cat file
foo
~$ cat file | sponge file
~$ cat file
foo
我知道您对简单的touch$file
不感兴趣,而是对文件的一种转换形式感兴趣
由于文件的转换可能会导致其临时损坏,因此当其他人可能同时读取文件时,将其放置到位是不好的
因为临时文件是您的最佳选择,并且只有在转换文件时,您才应该一步替换文件:
cat "$file" | process >"$file.$$"
mv "$file.$$" "$file"
这是最安全的一套操作
当然,我省略了诸如“检查文件是否真的存在”等操作,将其留给您。用“触摸$file”来更新其时间戳如何?不,实际上,您不能运行echo$(cat$file)>$file
。缺少引号意味着您的换行符变为空格,而全局也会扩展。touch
在这种情况下不起作用。到目前为止,我的解决方案运行良好,但我对细节知之甚少。为什么rm$file
?mv
是一种原子操作,即使在覆盖时也是如此;使用rm
意味着y您正在创建一个无需存在的争用条件。此外,您需要在变量周围加引号以确保真正的安全性——否则,如果在符合POSIX的shell上运行,则带有空格的文件名可以拆分为多个参数(除了zsh之外,几乎所有普通shell都可以)…此外,不要使用
$$`为此--mktemp的存在是有原因的;如果您正在向其他人可以创建文件的目录(如/tmp
)中写入文件,则预测临时文件的名称会让攻击者做出令人讨厌的事情@CharlesDuffy:谢谢你指出了mv
。我还在文件名周围加了引号(在Linux上很不喜欢,但我知道人们可能喜欢文件名中的空格;)……这不是个人偏好的问题,而是正确性的问题。我看到在某些应用程序中出现错误后,TB的生产数据被删除(非bash)代码将随机数据转储到文件名中,备份脚本对其进行了错误解释。很好,谢谢。我刚刚检查过,在我的特定情况下,亮度文件不能被数字以外的任何内容覆盖,这可能是我的解决方案能够正常工作的原因。