3

大家好。我正在设置一个 cron 作业来执行一个 bash 脚本,我担心下一个可能会在前一个结束之前开始。用谷歌搜索一下,解决这个问题的一种流行方法是flock命令,以下列方式使用:

flock -n lockfile myscript.sh
if [ $? -eq 1 ]; then
    echo "Previous script is still running!  Can't execute!"
fi

这很好用。但是,如果我想检查退出代码myscript.sh怎么办?无论它返回什么退出代码都会被flock's 覆盖,所以我无法知道它是否成功执行。

4

4 回答 4

6

看起来您可以使用 , 的替代形式flockflock <fd>其中<fd>是文件描述符。如果您将其放入子shell,并将该文件描述符重定向到您的锁定文件,那么flock 将等待直到它可以写入该文件(或者如果它无法立即打开它并且您已经通过,则会出错-n)。然后,您可以在子 shell 中执行所有操作,包括测试您运行的脚本的返回值:

(
  if flock -n 200
  then
    myscript.sh
    echo $?
  fi
) 200>lockfile
于 2009-12-26T21:54:57.110 回答
0
#!/bin/bash

if ! pgrep myscript.sh; then
  flock -n lockfile myscript.sh
fi

如果我理解正确,您要确保在 cron 尝试再次运行您的命令之前没有运行“myscript.sh”。假设这是对的,我们检查 pgrep 是否未能在进程列表中找到 myscript.sh,如果是,我们再次运行flock 命令。

于 2009-12-26T20:45:35.687 回答
0

也许这样的事情对你有用。

#!/bin/bash
RETVAL=0
lockfailed()
{
        echo "cannot flock"
        exit 1
}
(
        flock -w 2 42 || lockfailed
        false
        RETVAL=$?
        echo "original retval $RETVAL"
        exit $RETVAL
) 42>|/tmp/flocker
RETVAL=$?
echo "returned $RETVAL"
exit $RETVAL
于 2013-10-21T14:34:18.437 回答
0

根据flock man page,flock有一个-E或--exit-conflict-code标志你可以用来设置flock的退出代码在发生冲突的情况下应该是什么:

     -E, --conflict-exit-code 编号
              使用-n选项时使用的退出状态,并且存在冲突锁,或者-w选项正在使用中,并且达到超时。默认值为 1。数字必须在 0 到 255 的范围内。

手册页还指出:

退出状态
 
该命令对所有内容使用 sysexits.h 退出状态值,除非使用选项 -n 或 -w 报告获取锁失败,退出状态由 -E 选项给出,或默认为 1。-E 给出的退出状态必须在 0 到 255 的范围内。

当使用命令变体并执行子命令时,退出状态是子命令的退出状态。

因此,在使用“命令”变体时的 -n 或 -w 标志的情况下,您可以看到两种退出状态。

例子:

$ flock --exclusive /tmp/flock.lock bash -c 'exit 42'; echo $?
42

$ flock --exclusive /tmp/flock.lock flock --exclusive --nonblock --conflict-exit-code 100 /tmp/flock.lock bash -c 'exit 42'; echo $?
100

在第一个示例中,我们看到我们返回了正在使用flock 运行的进程的退出状态。在第二个示例中,我们正在为锁创建争用。在这种情况下,flock 本身会返回我们告诉它的状态码 (100)。如果您没有使用 --conflict-exit-code 标志指定值,它将返回 1。但是,我更喜欢设置不太常见的值,以防止与其他可能返回值 1 的进程/脚本混淆。

于 2021-11-18T21:13:24.577 回答