最好的方式来标记/确定过程后来杀死他们?

在我的linux启动脚本中,当我启动一个进程(openvpn用于这个例子,但问题是一般的任何进程);

openvpn --config /etc/myserver.conf 

什么是最好的方法来find它,并100%确定这是正确的过程,并在停止部分杀死它? 我通常使用像这样的东西:

 pid=$(ps -efww | grep -v grep | grep openvpn | grep /etc/myserver.conf | awk '{print $2}') 

当然,它几乎在所有的时间都可以运行,但是有时偶然会遇到与几乎相同的名称匹配的进程(例如myserver.conf-new),所以我正在寻找更好的方法。

  • 有些进程有办法将pid存储在某个地方,这很好,但是通常我只是基于某个文件夹中的pid来杀死进程而持怀疑态度。
  • Solaris有项目 ,并不是所有的玫瑰都是我有限的经验,因为你必须首先设置/ etc / projects,但它确实可以很容易标记和以后find进程。
  • 也许使用环境,比如设置一个像(MYID = myserver)的环境variables,然后用ps e -ef | grep MYID=myserver查找它 ps e -ef | grep MYID=myserver ? 仍然可能遭受意外匹配相同的问题。

我希望有一些容易的事情:

 launch --tag myserver openvpn --config /etc/myserver.conf 

 pgrep --tag myserver 

谢谢@Iain,@KyleSmith和@ M_1的帮助,帮助我开始了解服务器故障。 如果我在这里有更多的代表,我会+1你们。 (编辑:现在我有代表,+ 1周围)。

我要回答我自己的问题,因为我发现了一些我正在寻找的东西:一个避免与ps不精确的模式匹配的通用解决scheme,并且不使用pid文件。 这是完全主观的,这将是“最好”的方式,因为在使用pid文件unix中显然有一个长期和成功的历史,但这是我明确表示,我不喜欢的原因有多种,这些是:他们可以每个软件都有不同的要求,不同的软件,每个发行版都会有不同的performance,可能会被陈旧/覆盖,并且本质上不一定代表实际发生的事情。 我宁愿使用某种过程标签,询问内核并得到真正的答案。

修剪下来的例子:

 #!/bin/sh _TAG=d726cc7fa57a308afdc057b228a13f6d case "$1" in start) _TAG=$_TAG ./self-backgrounding-process _TAG=$_TAG ./non-self-backgrounding-process & ;; stop) pids=$(grep -l "\b_TAG=$_TAG\b" /proc/*/environ | cut -d/ -f3) [ -n "$pids" ] && kill $pids ;; esac 

关键是:

  • 使用标签的md5sum(不太可能被意外匹配的东西)
  • 在每个服务的启动脚本中使用不同的标记
  • 查询/ proc / * / environ以获取运行/相关/标记进程的准确列表
  • 使用grep与\ b来匹配单词边界以确保完全匹配

我不确定我喜欢污染环境,但是我不知道其他方式(例如Solaris项目)以任意方式标记linux进程,以便稍后请求内核。 至less,/ proc / <pid> / environ似乎反映了启动时的环境,不会受到进程之后可能造成的任何更改的影响 ,这表明这应该是可靠的,但是,这可能会有意想不到的变化。 这可能会或可能不会在Linux以外,取决于操作系统的/ proc和grep实现。

我想我会尝试一下,看看它是如何发展的。

一个不错的想法是使用一个简单的bash包装脚本来写入该应用程序的锁/ pid文件(通常在web服务器或数据库中使用),然后使用该文件来杀死这一个进程,如果需要的话。

不要害怕pidfiles,他们是真实的,通常由root拥有! 🙂

大多数发行版都使用标准函数或二进制文件来启动守护进程,并将生成的PID存储在文件中。 例如,在Debian中,你有一个带有--pidfile选项的start-stop-daemon。 其他发行版有/etc/rc.d/init.d/functions (或类似),用于启动守护进程。 检查发行版中包含的一些更通用的启动脚本。

尤其是对于openvpn,你可以使用--writepid /path/to/file命令行选项

 /usr/sbin/openvpn --writepid /var/run/openvpn/server.pid --config /etc/myserver.conf ... 

这将把openvpn主进程的PID写入指定的文件。

一般来说,你可以用一个小脚本包装你的程序,并使用bash $! 内置variables将pid写入文件

 #!/bin/bash yourcommand & echo $! >/path/to/pid.file