我想编写一个接受 URL 和输出 Markdown 文件的 shell 脚本,并将该 URL 和一些元数据添加到该文件的末尾。有可能这个脚本被并发调用,导致并发echo $some_multiline_thing >> file
。
根据这个问题,这可能会导致写入损坏的数据file
。如何同步写入,以便追加写入全部以原子方式发生? (附加的顺序对我来说并不重要。)
更新:我找到了一个半生不熟的解决方案
function sync-append() {
local file="$1"
local text="$2"
local lock_fd
{
exec {lock_fd}>>$file
flock -x "$lock_fd"
echo "$text" >> $file
} always {
exec {lock_fd}>&-
}
}
该解决方案依赖于 zsh 的always
,它可能不会被调用(例如,kill -9
)。
答案1
做就是了:
{
flock 1 &&
echo something
} >> "$file"
无论如何,当进程消失时,锁也消失了,所以你不必担心kill -s KILL
。
答案2
很可能您根本不必关心锁定。其条件是
- 您的系统不是非常旧的 Linux (<3.14)
- 从单个进程写入的数据量不超过 32K(或者更确切地说
getconf SSIZE_MAX
:)
看https://serverfault.com/questions/599486/what-is-the-size-of-an-atomic-write-to-disk-on-my-system