检测同一 ksh 的多次执行

问题描述 投票:0回答:1

我正在尝试检测

ksh script
是否已经在执行,以防止执行第二个实例。

该脚本由用户 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 调用发生冲突。

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

cron ksh
1个回答
0
投票

我忽略的一点是 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的行(包含在特殊的var中
      $$
    • 这样我就不需要过滤掉
      grep
      执行
    • 我必须将检查从
      1
      更改为
      0
      ,因为当前进程也被排除在
      ps
      结果之外
© www.soinside.com 2019 - 2024. All rights reserved.