我创建了一个脚本来验证计划的进程是否已经在运行,在这种情况下我会阻止执行并显示一条消息“脚本已经在运行”。问题是我插入了这几行代码
scriptToVerify="send_xxxx.sh ${1} ${2}";
num_proc=`ps auxww | grep "$scriptToVerify" | grep -v $$ | grep -v grep | awk /./ | /usr/bin/wc -l`;
if [ $num_proc -gt 1 ];
then
sl_log "---------------------------Warning---------------------------"
sl_log "$scriptToVerify Already running"
exit 0;
fi
在大量的脚本中(每个脚本都是预定的,有时是在同一时间)。我尝试了不同的解决方案:使用 flock 指令,使用锁定文件,但每次(即使是我上面写的指令)我的代码都工作了几周,然后开始报告“脚本已经运行”,但事实并非如此。
不幸的是,我无法管理调度程序,那么如何修改我的脚本以验证进程是否确实在运行?
最佳答案
使用 ps ... | grep ... | grep -v ... | grep -v grep | ...
通过其名称(或命令行)匹配进程充满了问题(如 $$
也匹配 PID 的一部分,如评论之一所述),使用 pgrep(1)
在这种情况下应该更容易,并且可以满足您的需求。
您也不必担心它的输出(即使它可以 -c
计算匹配项),而只需使用它会返回 0
的事实如果有任何匹配和 1
否则。使用 -f
在这种情况下匹配完整的命令行而不仅仅是进程名称。
if pgrep -f "${scriptToVerify}" >/dev/null; then
echo "'${scriptToVerify}' already running"
fi
如果您仍然遇到意外的不需要的匹配项,您也可以使其更详细一些(注意:某些进程可能会在调用 pgrep
和随后的 ps
之间终止):
matched_pids=$(pgrep -f "${scriptToVerify}")
if [[ -n "${matched_pids}" ]]; then
echo "Already running:"
ps -o pid,cmd -p ${matched_pids}
fi
您还可以确保模式不会意外匹配不需要的字符串(进程),例如使用 pgrep -f "${scriptToVerify}\$"
后面没有其他论点,甚至没有pgrep -f "^${scriptToVerify}\$"
如果scriptToVerify
是完全匹配,或者 pgrep -f "(^|\\<)${scriptToVerify}\$"
也许以 script basename 开头的值和所有参数都应该匹配。
关于linux - 检查双进程执行是否真实,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57198050/