我创建了一个脚本来验证计划的进程是否已在运行,在这种情况下,我阻止执行,并显示一条消息“脚本已在运行”。问题是我插入了这些代码行
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,但是每次(甚至我上面写的指令)我的代码都工作了几周,然后开始报告“脚本已在运行”,这也不是事实。
不幸的是,我无法管理调度程序,所以如何修改脚本以验证进程是否真正在运行?
答案 0 :(得分:1)
使用ps ... | grep ... | grep -v ... | grep -v grep | ...
来按名称(或命令行)来匹配进程会遇到很多问题(例如$$
也在注释之一中提到了PID的一部分),使用{{3 }}在这种情况下应该容易得多,并为您提供所需的内容。
您也不必担心其输出(即使它可以-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}\$"
可能以脚本basename开头的值和所有参数都应该匹配。