Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 用自身覆盖文件的最佳方法_Linux_Bash_Shell - Fatal编程技术网

Linux 用自身覆盖文件的最佳方法

Linux 用自身覆盖文件的最佳方法,linux,bash,shell,Linux,Bash,Shell,读取文件然后将内容写入同一文件的最快/最优雅的方式是什么 在Linux上,这并不总是与“触摸”文件相同,例如,如果文件代表某个硬件设备 对我有效的一种可能性是echo$(cat$file)>$file,但我想知道这是否是最佳做法。通常不能一步完成,因为写入文件会干扰读取。如果您在常规文件上尝试此操作,则重定向可能会在读取任何内容之前将文件清空 你最保险的办法是把它分成两步。如果需要,可以将其隐藏在函数调用后面 rewrite() { local file=$1 local co

读取文件然后将内容写入同一文件的最快/最优雅的方式是什么

在Linux上,这并不总是与“触摸”文件相同,例如,如果文件代表某个硬件设备


对我有效的一种可能性是
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)代码将随机数据转储到文件名中,备份脚本对其进行了错误解释。很好,谢谢。我刚刚检查过,在我的特定情况下,亮度文件不能被数字以外的任何内容覆盖,这可能是我的解决方案能够正常工作的原因。