我正在为启动服务脚本编写停止例程:
do_stop()
{
rm -f $PIDFILE
pkill -f $DAEMON || return 1
return 0
}
问题是pkill(与killall相同)也匹配代表脚本本身的进程,它基本上终止了自己。如何解决?
答案 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
中看到相关示例