使用pkill防止进程自杀

时间:2013-04-01 09:01:25

标签: linux bash

我正在为启动服务脚本编写停止例程:

do_stop()
{
  rm -f $PIDFILE
  pkill -f $DAEMON || return 1
  return 0
}

问题是pkill(与killall相同)也匹配代表脚本本身的进程,它基本上终止了自己。如何解决?

3 个答案:

答案 0 :(得分:11)

您可以从结果中明确过滤出当前的PID:

kill $(pgrep -f $DAEMON | grep -v ^$$\$)

要正确使用-f标志,请务必提供守护程序的完整路径,而不仅仅是子字符串。这将阻止您杀死脚本(并消除对上述grep的需要),并且还可以杀死碰巧共享守护程序名称的所有其他系统进程。

答案 1 :(得分:6)

pkill -f接受一个完整的正则表达式。所以而不是pkill -f $DAEMON你应该使用:

pkill -f "^"$DAEMON

要确保只有进程名称以给定的守护程序名称开头,才会被终止。

更好的解决方案将在您启动流程时将流程的pid(进程ID)保存在文件中。并且为了停止该过程,只需读取文件以使进程ID停止/终止。

答案 2 :(得分:1)

根据你的问题判断,你并不是很难使用pgrep和pkill,所以这里有一些常用的选项。

1)使用killproc/etc/init.d/functions中的/lib/lsb/init-functions(适用于您的发行版和Linux版)。如果您正在编写服务脚本,如果您使用其他服务之一作为示例,则可能已包含此文件。

Usage: killproc [-p pidfile] [ -d delay] {program} [-signal]

使用它的主要优点是它发送SIGTERM,等待进程终止并仅在必要时发送SIGKILL。

2)您还可以使用killproc的秘诀,即使用pidof找到要杀死的进程ID,其中-o选项用于排除特定进程。 -o的参数可以是$$,当前进程ID,或%PPID,这是pidof解释为调用pidof的脚本的特殊变量。最后,如果守护进程是一个脚本,那么你需要-x所以你试图用它的名字杀死脚本而不是杀死bash或python。

for pid in $(pidof -o %PPID -x progd); do
    kill -TERM $pid
done

您可以在文章Bash: How to check if your script is already running

中看到相关示例