我正在使用 Bash 脚本并遇到这种情况:
一个 bash 脚本会将内容写入文件,另一个 bash 脚本将从同一文件中读取内容。
在这种情况下,锁定文件是必要的吗?我想我不需要使用lockfile,因为只有一个读取过程和一个写入过程,但我不确定。
write.sh:
#!/bin/bash
echo 'success' > tmp.log
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
等。
虽然许多程序员忽略了这一点,但您可能会遇到问题,因为写入文件不是原子的。当作者这样做时
echo success > tmp.log
它可以分为两个(或更多(部分:首先它写suc
,然后写cessn
。
如果读取器在这些步骤之间执行,则它可能只得到suc
而不是整个success
行。使用锁文件可以防止此争用条件。
从 shellecho
命令进行短写不太可能发生这种情况,这就是为什么大多数程序员不担心它的原因。但是,如果编写器是使用缓冲输出的 C 程序,则可以在任意时间刷新缓冲区,这可能会以部分行结尾。
此外,由于读取器每次都从头开始读取文件,因此您不必担心从上一个停止的地方开始读取。
执行此操作的另一种方法是让编写器写入具有不同名称的文件,然后将该文件重命名为读者要查找的内容。重命名是原子的,因此您可以保证读取所有内容或什么都不读取。
至少从您的示例中,看起来read.sh
并不真正关心写入tmp.log
的内容,只是write.sh
创建了文件。在这种情况下,read.sh
需要检查的只是文件是否存在。
write.sh
可以简单地
: > tmp.log
read.sh
变成
until [ -e tmp.log ]; do
sleep 3
done
echo "done"