18

避免同一脚本的两个实例同时运行的典型方法如下所示:

[ -f ".lock" ] && exit 1
touch .lock
# do something
rm .lock

有没有更好的方法来锁定来自 shell 脚本的文件,避免竞争条件?必须改用目录吗?

4

5 回答 5

24

是的,示例脚本中确实存在竞争条件。您可以使用 bash 的noclobber选项来在比赛中失败,当不同的脚本潜入-f测试和touch.

以下是说明该机制的示例代码片段(受本文启发):

if (set -o noclobber; echo "$$" > "$lockfile") 2> /dev/null; 
then
   # This will cause the lock-file to be deleted in case of a
   # premature exit.
   trap 'rm -f "$lockfile"; exit $?' INT TERM EXIT

   # Critical Section: Here you'd place the code/commands you want
   # to be protected (i.e., not run in multiple processes at once).

   rm -f "$lockfile"
   trap - INT TERM EXIT
else
   echo "Failed to acquire lock-file: $lockfile." 
   echo "Held by process $(cat $lockfile)."
fi
于 2008-11-28T12:23:32.037 回答
10

尝试群命令:

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。

于 2009-10-15T11:14:12.257 回答
4

锁定您的脚本(防止并行运行)

http://wiki.bash-hackers.org/howto/mutex

供参考。

于 2011-03-06T09:13:05.353 回答
0

创建一个目录是原子的,如果你不使用它已经存在就会失败-p,所以

 mkdir $lockName || exit 1

作品。

...但flock改为使用。

于 2020-08-10T18:12:25.983 回答
-1

似乎我找到了一个更简单的解决方案: man lockfile

于 2008-11-28T12:28:34.693 回答