这是使用文件系统创建锁的标准方法。例如,visudo使用它:
[ -f ".lock" ] && exit 1
touch .lock
# do something
rm .lock
1)我很困惑,因为有竞争条件,但Linux使用它
2)有没有更好的方法来锁定shell中的文件?
3)或者我必须使用目录吗?
找到解决方案:man lockfile。
答案 0 :(得分:21)
是的,示例脚本确实存在竞争条件。您可以使用bash的noclobber选项,以便在比赛时遇到失败,当不同的脚本在测试和触摸之间潜入时。
它描述了here。我摘录了关键部分,带有几个注释(以BK为前缀):
可能的解决方案是使用IO重定向和bash的noclobber模式,它不会重定向到现有文件。我们可以使用类似的东西:
if ( set -o noclobber; echo "$$" > "$lockfile") 2> /dev/null;
then
# BK: this will cause the lock file to be deleted in case of other exit
trap 'rm -f "$lockfile"; exit $?' INT TERM EXIT
# critical-section BK: (the protected bit)
rm -f "$lockfile"
trap - INT TERM EXIT
else
echo "Failed to acquire lockfile: $lockfile."
echo "Held by $(cat $lockfile)"
fi
答案 1 :(得分:9)
尝试flock命令:
exec 200>"$LOCK_FILE"
flock -e -n 200 || exit 1
如果锁定文件被锁定,它将退出。它是原子的,它可以在最新版本的NFS上运行。
我做了一个测试。我创建了一个包含0的计数器文件,并在两个服务器上同时循环执行以下500次:
#!/bin/bash
exec 200>/nfs/mount/testlock
flock -e 200
NO=`cat /nfs/mount/counter`
echo "$NO"
let NO=NO+1
echo "$NO" > /nfs/mount/counter
一个节点正在与另一个节点争夺锁定。当两个运行完成后,文件内容为1000.我已多次尝试,它总是有效!
注意:NFS客户端是RHEL 5.2,使用的服务器是NetApp。
答案 2 :(得分:2)
答案 3 :(得分:0)
好像我找到了一个更简单的解决方案:man lockfile
答案 4 :(得分:0)
创建目录是原子的,如果不使用-p
,创建目录将失败,因此
mkdir $lockName || exit 1
有效。
...但是改用flock
。