Cron 检测同一ksh的多个执行

Cron 检测同一ksh的多个执行,cron,ksh,Cron,Ksh,我试图检测是否已在执行ksh脚本,以防止执行第二个实例 用户cronjob每分钟调用一次脚本: * * * * * /home/user/job.ksh TESTACTION &>/dev/null 我在脚本开头添加了一个守卫: #!/usr/bin/ksh LOGDIR="/home/user" processes=$(/bin/ps ux | /bin/grep -i "job.ksh TESTACTION" | /bin/grep -v grep | /bin/grep

我试图检测是否已在执行
ksh脚本
,以防止执行第二个实例

用户cronjob每分钟调用一次脚本:

* * * * * /home/user/job.ksh TESTACTION &>/dev/null
我在脚本开头添加了一个守卫:

#!/usr/bin/ksh

LOGDIR="/home/user"

processes=$(/bin/ps ux | /bin/grep -i "job.ksh TESTACTION" | /bin/grep -v grep | /bin/grep -c "\/usr\/bin\/ksh")
if (( $processes > 1 )); then
    datetime=$(/bin/date +'%Y.%m.%d %H:%M:%S')
    /bin/echo -e "${datetime} - skipped execution for other ${processes} active process" >> "${LOGDIR}/multiple_ksh_check.log"
    exit 0
fi
令我惊讶的是,
if
条件经常得到满足,但并不总是得到满足,因为我可以从日志文件中看到这一点

考虑到出于测试目的,我重现了这个代码片段的问题,这意味着脚本会持续几毫秒,而不会持续一分钟,从而与下一个cronjob调用发生冲突


我错过了什么?我可以尝试什么?

我缺少的一点是shell可以在其他进程中生成子shell,这就是为什么
ps
发现的行数比预期的多

在@markp的帮助下,我重写了这样的条件

processes=$(/bin/ps x -o pid,ppid,args | /bin/grep -vw $$ | /bin/grep -i "job.ksh TESTACTION" | /bin/grep -c "\/usr\/bin\/ksh")
if (( $processes > 0 )); then
     exit 0
fi
以下是要点:

  • ps
    的输出格式化为包含pid和父pid信息
    • 我过滤掉包含当前进程pid的行(包含在特殊变量
      $$
      中)
    • 这样我就不需要过滤掉
      grep
      执行
    • 我不得不将检查从
      1
      更改为
      0
      ,因为当前流程也被排除在
      ps
      结果之外

    • 我遗漏的一点是shell可以在其他进程中生成子shell,这就是为什么
      ps
      找到的行比预期的多

      在@markp的帮助下,我重写了这样的条件

      processes=$(/bin/ps x -o pid,ppid,args | /bin/grep -vw $$ | /bin/grep -i "job.ksh TESTACTION" | /bin/grep -c "\/usr\/bin\/ksh")
      if (( $processes > 0 )); then
           exit 0
      fi
      
      以下是要点:

      • ps
        的输出格式化为包含pid和父pid信息
        • 我过滤掉包含当前进程pid的行(包含在特殊变量
          $$
          中)
        • 这样我就不需要过滤掉
          grep
          执行
        • 我不得不将检查从
          1
          更改为
          0
          ,因为当前流程也被排除在
          ps
          结果之外

      我将从一点简单的调试开始;当
      $processs>1
      时,也将整套
      ps
      数据(即未通过
      grep
      调用过滤)转储到日志文件中;使用全套
      ps
      数据,您可能会发现逻辑和/或shell脚本的其他信息存在问题,以解释
      $processs>1
      的原因。另外,请查看这一点,这可能适用于您的情况。我尝试转储所有可能的
      ps
      输出,以确保逻辑正常工作。在我看来,子流程理论似乎是更合理(也是最后一个)的解释,我认为最终罪魁祸首是
      $(/bin/ps-ux)
      ,但我该如何解决这个问题呢?我通常会抓住当前调用的pid(
      mypid=$
      );然后过滤掉所有包含
      $mypid
      ps
      结果;这应该过滤掉当前进程(进程=
      $mypid
      )以及任何(短期)子进程(父进程=
      $mypid
      );类似于egrep-v“${mypid}”。。。请注意${mypid}之前/之后的空格,以便在罕见的情况下,当mypid=123时,我们不会过滤掉1234。是的,我正在研究这样一个解决方案,它的灵感来自于使用
      grep
      -w
      选项来防止您提到的子字符串问题。还有一些测试,但我想这就是我想要的,谢谢,我会从一些简单的调试开始;当
      $processs>1
      时,也将整套
      ps
      数据(即未通过
      grep
      调用过滤)转储到日志文件中;使用全套
      ps
      数据,您可能会发现逻辑和/或shell脚本的其他信息存在问题,以解释
      $processs>1
      的原因。另外,请查看这一点,这可能适用于您的情况。我尝试转储所有可能的
      ps
      输出,以确保逻辑正常工作。在我看来,子流程理论似乎是更合理(也是最后一个)的解释,我认为最终罪魁祸首是
      $(/bin/ps-ux)
      ,但我该如何解决这个问题呢?我通常会抓住当前调用的pid(
      mypid=$
      );然后过滤掉所有包含
      $mypid
      ps
      结果;这应该过滤掉当前进程(进程=
      $mypid
      )以及任何(短期)子进程(父进程=
      $mypid
      );类似于egrep-v“${mypid}”。。。请注意${mypid}之前/之后的空格,以便在罕见的情况下,当mypid=123时,我们不会过滤掉1234。是的,我正在研究这样一个解决方案,它的灵感来自于使用
      grep
      -w
      选项来防止您提到的子字符串问题。还有一些测试,但我想这就是我想要的,谢谢