检查双重处理执行是否真实

时间:2019-07-25 08:58:06

标签: linux bash

我创建了一个脚本来验证计划的进程是否已在运行,在这种情况下,我阻止执行,并显示一条消息“脚本已在运行”。问题是我插入了这些代码行

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指令,使用lockfile,但是每次(甚至我上面写的指令)我的代码都工作了几周,然后开始报告“脚本已在运行”,这也不是事实。

不幸的是,我无法管理调度程序,所以如何修改脚本以验证进程是否真正在运行?

1 个答案:

答案 0 :(得分:1)

使用ps ... | grep ... | grep -v ... | grep -v grep | ...来按名称(或命令行)来匹配进程会遇到很多问题(例如$$也在注释之一中提到了PID的一部分),使用{{3 }}在这种情况下应该容易得多,并为您提供所需的内容。

您也不必担心其输出(即使它可以-c进行匹配计数),而只需使用以下事实:如果有任何匹配项,它将返回01除此以外。在这种情况下,请使用-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}\$"可能以脚本basename开头的值和所有参数都应该匹配。