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

Man*_*nde 27 unix bash shell concurrency semaphore

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

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

Pau*_*bel 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
Run Code Online (Sandbox Code Playgroud)

请点击此链接了解有关清理和其他项目的更多详细信息.

  • 锁定的目的不是直到释放锁定为止.这个脚本应该像while循环中的mkdir一样,直到它成功并且一旦完成作业,脚本就会删除tmp目录吗? (5认同)
  • @Pocha 这是它可以工作的一种方式,但您可能同样希望脚本退出并给出解释,这就是我来到这里的原因)。如果所描述的行为是您想要的,则应该很容易修改此答案以实现这一目标。 (2认同)

she*_*ter 13

有关Bash中文件锁定的讨论,请参阅BashFAQProcessManagment.

将您的问题标记为shell(仅限)可以限制可以帮助您的人数.你可能想添加unix,ksh,bash.

关于这个主题的问题/答案已经在SO上发布了很多

我希望这有帮助.

  • 如果这是重复的,你能指出一个特别的吗? (6认同)
  • 我没有说它是重复的,目的是指出一个相对较新的用户通过搜索更彻底的搜索SO我查找`[bash] file lock`和`[bash] mutex`并发现了许多会添加透视.祝好运. (2认同)

PSk*_*cik 6

您可以使用该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
Run Code Online (Sandbox Code Playgroud)

用法示例:

./mx & ./mx & ./mx & #will run one at a time cuz of the lock
Run Code Online (Sandbox Code Playgroud)

(

回答马西莫的观点:

如果你不想硬编码一个文件编号(如果你不是硬编码0,1或2,它应该很少有问题,但无论如何),那么在bash中(但不是在一个只有POSIX的shell中)你可以分配让系统为你选择一个fd:

{
flock $fd
#...
} {fd}<lock
Run Code Online (Sandbox Code Playgroud)

)

  • @Massimo 感谢您指出这一点。我已经在编辑中解决了你的观点。 (2认同)
  • 不错的收获!使用 bash 30 年,您将永远不会停下来学习新的非常有用的东西。请注意,这需要 [bash 4.1](https://wiki.bash-hackers.org/scripting/bashchanges) 及更高版本。使用 `local -n` (bash 4.3),我们可以获得所有功能的全部功能:`{var[sub]}&lt;file`,也可以执行:`x() { local -na="$1" b =“$2”c =“$3”;执行{a}&lt;&amp;0 {b}&gt;&amp;1 {c}&gt;&amp;2; }` 然后`声明-AA;x "A[t1]" "A[t2]" "A[t3]"`,但它甚至可以执行 bash 中没有的类似 `{!var}&lt;file` 的操作:`x=a1 y=a2 z=a3;x“$x”“$y”“$z”` (2认同)
  • @guru_florida `: &gt;&gt; lock` 使用 :/true do-nothing-successively 命令和 `&gt;&gt; lock` (追加或创建)重定向来创建名为 lock 的文件,除非该文件已存在。这只是机制的演示。当然,您通常希望锁定文件位于当前目录之外的其他位置。;-) (2认同)