【问题标题】:How do I check the exit code of a command executed by flock?如何检查flock执行的命令的退出代码?
【发布时间】:2010-12-30 04:12:23
【问题描述】:

大家好。我正在设置一个 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覆盖,所以我无法知道它是否成功执行。

【问题讨论】:

    标签: bash cron exit-code file-locking flock


    【解决方案1】:
    #!/bin/bash
    
    if ! pgrep myscript.sh; then
      flock -n lockfile myscript.sh
    fi
    

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

    【讨论】:

      【解决方案2】:

      看起来您可以使用flockflock <fd> 的替代形式,其中<fd> 是文件描述符。如果你把它放到一个子shell中,并将那个文件描述符重定向到你的锁文件,那么flock会一直等到它可以写入那个文件(或者如果它不能立即打开它并且你已经传递了-n,则会出错) .然后你可以在你的子shell中做所有事情,包括测试你运行的脚本的返回值:

      (
        if flock -n 200
        then
          myscript.sh
          echo $?
        fi
      ) 200>lockfile
      

      【讨论】:

      • 或者,如果 OP 稍后需要使用 $?,请摆脱子外壳并显式打开/关闭,例如 exec 200>lockfile; if ... fi; exec 200>&-
      【解决方案3】:

      也许这样的东西对你有用。

      #!/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
      

      【讨论】:

        【解决方案4】:

        根据flock的手册页,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 的进程/脚本混淆。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2023-03-27
          • 2013-09-14
          • 2018-03-29
          • 2017-01-19
          • 2021-11-10
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多