如何同步 shell 脚本中的追加写入?

如何同步 shell 脚本中的追加写入?

我想编写一个接受 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

很可能您根本不必关心锁定。其条件是

  1. 您的系统不是非常旧的 Linux (<3.14)
  2. 从单个进程写入的数据量不超过 32K(或者更确切地说getconf SSIZE_MAX:)

https://serverfault.com/questions/599486/what-is-the-size-of-an-atomic-write-to-disk-on-my-system

相关内容