bash 使用 pkill 防止进程杀死自己

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15740481/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 05:02:45  来源:igfitidea点击:

Prevent process from killing itself using pkill

linuxbash

提问by kaspersky

I'm writing a stop routine for a start-up service script:

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

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

The problem is that pkill (same with killall) also matches the process representing the script itself and it basically terminates itself. How to fix that?

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

采纳答案by user4815162342

You can explicitly filter out the current PID from the results:

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

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

To correctly use the -fflag, be sure to supply the whole path to the daemon rather than just a substring. That will prevent you from killing the script (and eliminate the need for the above grep) and also from killing all other system processes that happen to share the daemon's name.

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

回答by anubhava

pkill -faccepts a full blown regex. So rather than pkill -f $DAEMONyou should use:

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

pkill -f "^"$DAEMON

To make sure only if process name starts with the given daemon name then only it is killed.

确保仅当进程名称以给定的守护进程名称开头时,才将其杀死。

A better solutionwill be to save pid (Proces Id) of the process in a file when you start the process. And for the stopping the process just read the file to get the process id to be stopped/killed.

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

回答by Chad Skeeters

Judging by your question, you're not hard over on using pgrep and pkill, so here are some other options commonly used.

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

1) Use killprocfrom /etc/init.d/functionsor /lib/lsb/init-functions(which ever is appropriate for your distribution and version of linux). If you're writing a service script, you may already be including this file if you used one of the other services as an example.

1)使用killprocfrom/etc/init.d/functions/lib/lsb/init-functions(适合您的发行版和 linux 版本)。如果您正在编写服务脚本,并且您使用其他服务之一作为示例,那么您可能已经包含此文件。

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

The main advantage to using this is that it sends SIGTERM, waits to see if the process terminates and sends SIGKILL only if necessary.

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

2) You can also use the secret sauce of killproc, which is to find the process ids to kill using pidofwhich has a -ooption for excluding a particular process. The argument for -ocould be $$, the current process id, or %PPID, which is a special variable that pidof interprets as the script calling pidof. Finally if the daemon is a script, you'll need the -x so your trying to kill the script by it's name rather than killing bash or python.

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

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

You can see an example of this in the article Bash: How to check if your script is already running

您可以在Bash:如何检查您的脚本是否已在运行一文中看到这样的示例