且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如果调用了另一个实例,请重新运行bash脚本

更新时间:2023-12-05 13:51:52

它们并不是所有人的最爱,但由于它们是原子性的,所以我一直非常喜欢用于创建锁文件的符号链接.例如:

They're not everone's favourite, but I've always been a fan of symbolic links to make lockfiles, since they're atomic. For example:

lockfile=/var/run/`basename $0`.lock
if ! ln -s "pid=$$ when=`date '+%s'` status=$something" "$lockfile"; then
  echo "Can't set lock." >&2
  exit 1
fi

通过将有用的信息直接编码到链接目标中,可以消除写入文件时引入的竞争条件.

By encoding useful information directly into the link target, you eliminate the race condition introduced by writing to files.

也就是说,Dennis发布的链接提供了更多有用的信息,在编写更多脚本之前,您可能应该尝试理解这些信息.上面的示例与 BashFAQ/045 有关,它建议对做类似的事情mkdir .

That said, the link that Dennis posted provides much more useful information that you should probably try to understand before writing much more of your script. My example above is sort of related to BashFAQ/045 which suggests doing a similar thing with mkdir.

如果我正确理解了您的问题,则可以通过使用两个锁定文件来实现(略微不可靠)您想要做的事情.如果设置第一个锁失败,我们尝试第二个锁.如果设置第二个锁失败,则退出.如果第一个锁在我们检查之后但在检查第二个现有锁之前被删除,则存在错误.如果您可以接受此错误级别,那就太好了.

If I understand your question correctly, then what you want to do might be achieved (slightly unreliably) by using two lock files. If setting the first lock fails, we try the second lock. If setting the second lock fails, we exit. The error exists if the first lock is delete after we check it but before check the second existant lock. If this level of error is acceptable to you, that's great.

这是未经测试的;但是在我看来,这是合理的.

This is untested; but it looks reasonable to me.

#!/usr/local/bin/bash

lockbase="/tmp/test.lock"

setlock() {
  if ln -s "pid=$$" "$lockbase".$1 2>/dev/null; then
    trap "rm \"$lockbase\".$1" 0 1 2 5 15
  else
    return 1
  fi
}

if setlock 1 || setlock 2; then
  echo "I'm in!"
  do_something_amazing
else
  echo "No lock - aborting."
fi