背景
需要一个shell 脚本检测一下进程是否存在,如果存在则直接kill 掉
问题处理
查看进程id
ps -ef|grep node_exporter|grep -v grep|awk '{print $2}'
如果应用进程是存在的且只有一个进程,在脚本中打印会发现有三个进程id,其中有两个进程是用不到的,且多出来的两个进程id和当前脚本子进程相关,为什么会有两个无关的进程id呢?理论上来讲主机上只有这一个关键词的进程,排查发现是因为定义的脚本名称包含了node_exporter所导致。
知识点补充
shell脚本在执行时,会启动子shell的进程。作为主shell的子进程,子shell将shell脚本中的命令作为批处理运行(因此称为“批处理进程”)。
在bash中,子shell进程的PID存储在一个特殊的变量‘$$’中。这个变量只读,你不可以在脚本中修改它。
除了$$, bash shell还会导出其他的只读变量。比如,PPID存储子shell父进程的ID(也就是主shell)。UID存储了执行这个脚本的当前用户ID
echo $PPID echo UID
解决方法
优化获取进程id方式
ps -ef|grep node_exporter|grep -v grep|grep -v $$|awk '{print $2}'
这样获得的进程就会过滤掉当前脚本的进程,问题处理
脚本伪代码供参考
# 检查 node_exporter 进程是否存在,存在则直接kill 掉 check_node_exporter_status(){ echo "check node exporter status start " node_exporer_proc=`ps -ef|grep node_exporter|grep -v grep|grep -v $$|awk '{print $2}'` if [[ $node_exporer_proc != "" ]]; then echo "node_exporter process id is $node_exporer_proc" sudo kill $node_exporer_proc fi echo "check node exporter status end " }