代码之家  ›  专栏  ›  技术社区  ›  Yves

是否需要锁文件来读取和写入两个进程的同一文件

  •  2
  • Yves  · 技术社区  · 6 年前

    我正在使用Bash脚本并遇到这样的情况:

    一个bash脚本将把东西写到一个文件中,另一个bash脚本将从同一个文件中读取东西。

    在这种情况下,是否需要锁文件?我想我不需要使用lockfile,因为只有一个读取过程和一个写入过程,但我不确定。

    Bash write.sh:点击

    #!/bin/bash
    
    echo 'success' > tmp.log
    


    Bash read.sh:点击

    #!/bin/bash
    while :
    do
        line=$(head -n 1 ./tmp.log)
        if [[ "$line" == "success" ]]; then
            echo 'done'
            break
        else
            sleep 3
        fi
    done
    

    顺便说一下 write.sh 会写几个关键词,比如 success , fail 等。

    2 回复  |  直到 6 年前
        1
  •  2
  •   Barmar 0___________    6 年前

    虽然许多程序员忽略了这一点,但您可能会遇到一个问题,因为对文件的写入不是原子的。当作者这样做的时候

    echo success > tmp.log
    

    它可以分成两个(或更多)部分:首先它写 suc ,然后它写道 cess\n .

    如果读卡器在这些步骤之间执行,它可能会 苏克 而不是整个 success 行。使用锁文件可以防止这种竞争条件。

    这不太可能发生在shell的短写操作中 echo 命令,这就是为什么大多数程序员不担心它。但是,如果编写器是使用缓冲输出的C程序,则可以在任意时间刷新缓冲区,这可能以部分行结尾。

    另外,由于读卡器每次都从一开始就在读取文件,所以您不必担心从上一次停止的地方开始读取。

    另一种方法是让编写器写入一个具有不同名称的文件,然后将该文件重命名为读卡器正在查找的文件。重命名是原子的,所以你一定要读所有的或什么都不读。

        2
  •  1
  •   chepner    6 年前

    至少从你的例子来看 read.sh 真的很在乎 什么 被写入 tmp.log ,仅此而已 write.sh 已创建文件。在这种情况下,所有 阅读.sh 需要检查的是文件是否存在。

    写入.sh 可能只是

    : > tmp.log
    

    阅读.sh 变成

    until [ -e tmp.log ]; do
      sleep 3
    done
    echo "done"