我正在寻找shell脚本中的互斥/信号量/并发机制。 考虑以下情况: 除非“a”用户不关闭共享文件,否则“b”用户不应该打开/更新它。 我只是想知道如何在shell脚本中实现互斥,信号量,关键部分等。
在shell脚本中实现锁定机制[文件级别]的最简单方法是什么?
答案 0 :(得分:39)
BashFAQ shellter指出有一些很好的例子。基本的想法,我在这里移动,所以页面是自包含的,是使用同时测试和设置的操作:mkdir
如果目录存在,mkdir将失败,如果不存在则将失败。这是一个原子操作,您可以像这样使用它来在shell脚本中执行互斥(来自上面的BashFAQ)
# Bourne
lockdir=/tmp/myscript.lock
if mkdir "$lockdir"
then # directory did not exist, but was created successfully
echo >&2 "successfully acquired lock: $lockdir"
# continue script
else # failed to create the directory, presumably because it already exists
echo >&2 "cannot acquire lock, giving up on $lockdir"
exit 0
fi
点击链接了解有关清理和其他项目的详细信息。
答案 1 :(得分:12)
有关Bash中文件锁定的讨论,请参阅BashFAQ和ProcessManagment。
将您的问题标记为shell(仅限)可以限制可以帮助您的人数。你可能想添加unix,ksh,bash。
这个主题已经在S.O。
上发布了很多问题/答案我希望这会有所帮助。
答案 2 :(得分:5)
您可以使用flock
实用程序锁定文件/将其用作互斥锁。
示例:
#!/bin/sh -eu
#advanced bash stuff not needed
: >> lock #create a file if it doesn't exist
{
flock 3 #lock file by filedescriptor
echo $$ working with lock
sleep 2
echo $$ done with lock
} 3<lock
使用示例:
./mx & ./mx & ./mx & #will run one at a time cuz of the lock
(
回复massimo的观点:
如果您不想对文件编号进行硬编码(如果您不是硬编码0,1或2,则很少会出现问题,但无论如何),然后在bash中 (但不能在一个只有POSIX的shell中)你可以指定让系统为你选择一个fd:
{
flock $fd
#...
} {fd}<lock
)
答案 3 :(得分:1)
您将希望防止持续轮询,并改用中断之类的机制。
为此使用内存中的文件(运行目录),并等待被另一个进程更改:
mutex="/run/user/$(id -u)/mutex"
waitMutex () {
tail --follow --lines=0 "${mutex}" |
head -n1 >/dev/null
echo > "${mutex}"
}