shell脚本中是否有任何互斥/信号量机制?

时间:2011-07-29 08:01:00

标签: bash shell unix concurrency semaphore

我正在寻找shell脚本中的互斥/信号量/并发机制。 考虑以下情况: 除非“a”用户不关闭共享文件,否则“b”用户不应该打开/更新它。 我只是想知道如何在shell脚本中实现互斥,信号量,关键部分等。

在shell脚本中实现锁定机制[文件级别]的最简单方法是什么?

4 个答案:

答案 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中文件锁定的讨论,请参阅BashFAQProcessManagment

将您的问题标记为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}"
}