检测同一 ksh 的多次执行
Detect multiple executions of same ksh
我正在尝试检测 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 调用发生冲突。
我错过了什么?我可以尝试什么?
我遗漏的一点是 shell 可以在其他进程中生成子 shell,这就是为什么 ps
发现的行比预期的多。
在@markp 和this answer 的帮助下,我重写了这样的条件
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
结果中排除
我正在尝试检测 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 调用发生冲突。
我错过了什么?我可以尝试什么?
我遗漏的一点是 shell 可以在其他进程中生成子 shell,这就是为什么 ps
发现的行比预期的多。
在@markp 和this answer 的帮助下,我重写了这样的条件
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
结果中排除
- 我过滤掉包含当前进程'pid的行(包含在特殊var