【问题标题】:Prevent process from killing itself using pkill防止进程使用 pkill 杀死自己
【发布时间】:2013-04-01 09:01:24
【问题描述】:

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

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

问题在于 pkill(与 killall 相同)也匹配代表脚本本身的进程,并且它基本上会自行终止。如何解决?

【问题讨论】:

  • 使用 pgrep 和循环然后杀死?
  • 我本来打算这样做,但在这里问了这个问题,以防有更简单的解决方案。

标签: linux bash


【解决方案1】:

您可以从结果中显式过滤掉当前的PID:

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

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

【讨论】:

  • For me in bash pgrep 还找到了子shell 的 pid 并在试图杀死它时打印一个丑陋的警告。
【解决方案2】:

pkill -f 接受完整的正则表达式。因此,您应该使用 pkill -f $DAEMON 而不是:

pkill -f "^"$DAEMON

确保只有当进程名称以给定的守护进程名称开头时才会被杀死。

更好的解决方案是在启动进程时将进程的 pid(进程 ID)保存在文件中。对于停止进程,只需读取文件以获取要停止/终止的进程 ID。

【讨论】:

    【解决方案3】:

    从你的问题来看,你对使用 pgrep 和 pkill 并不难,所以这里有一些常用的其他选项。

    1) 使用/etc/init.d/functions/lib/lsb/init-functions 中的killproc(适用于您的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中看到一个例子

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-02
      • 2022-01-18
      • 2011-06-05
      • 1970-01-01
      • 1970-01-01
      • 2013-07-20
      • 1970-01-01
      • 2011-12-12
      相关资源
      最近更新 更多