如何优雅地杀死一个带有名字的守护进程?

如何优雅地杀死一个带有名字的守护进程?

我通常用 杀死一个进程killall

killall markdoc

但我不确定这个命令是否会正常终止该进程。该命令是否实现了优雅终止?如果没有,我怎样才能优雅地杀死一个进程及其名称?

答案1

你的问题不清楚,你在标题中谈论守护进程,但在正文中只谈论通用进程。

对于守护进程有特定的方法来停止它,例如在 Debian 中你有

    service daemon-name stop

或者

    /etc/init.d/daemon-name stop

其他发行版/操作系统中使用的其他 initscript 标准也存在类似的语法。

要终止非守护进程,假设它在某种程度上失去控制,您可以安全地使用killallpkill,因为它们默认使用SIGTERM(15) 信号,并且任何正确编写的应用程序都应该在接收到此信号时捕获并正常退出。请考虑到,如果有多个同名进程,这些实用程序可能会杀死多个进程。

如果这不起作用,您可以尝试SIGINT(2),然后尝试SIGHUP(1),最后采用SIGKILL(9)。应用程序无法捕获最后一个信号,因此它无法执行任何清理。因此,应尽可能避免这种情况。

pkill和都killall接受 形式的信号参数-NAME,如下所示

pkill -INT process-name

答案2

在类似 BSD 和其他发行版上,您通常会在 /etc/rc.d/ 中包含脚本,这些脚本通常管理系统中守护进程的启动、重新启动和停止。要停止守护进程,您可以使用绝对路径调用脚本,例如:

# /etc/rc.d/acpid stop

或使用命令:

# rc.d stop acpid

我强烈建议尝试这个脚本来显示您的系统启动和停止的守护进程:

#!/bin/bash

chk_status(){
  target=$1
  if [[ $target != "functions" && $target !=  "functions.d" ]]
  then
    if [[ -f "/var/run/daemons/$target" ]]
     then
       stat="\e[1;32m[RUNNING]"
     else
       stat="\e[1;31m[STOPPED]"
     fi

    printf "$stat \t\e[1;34m$target\e[0;0m\n"
  fi
}

daemons=($(for daemon in /etc/rc.d/*; do echo "${daemon#\/etc\/rc.d\/}"; done))

if [[ $1 != "" ]]
then
 chk_status $1
else
 for d in "${daemons[@]}"; do
   chk_status $d
 done | sort
fi

答案3

检查脚本killproc中是否有可用的函数/etc/init.d/functions,获取文件并使用该函数。或者使用pgreppkill实用程序来检查它们是否按预期工作,然后使用它们。示例: pkill -SIGTERM mysqld在被杀死之前,将发送 TERM Kill 信号以使 mysqld 执行安全关闭并将数据库刷新到磁盘上。

相关内容