在我的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),所以我正在寻找更好的方法。
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
关键是:
我不确定我喜欢污染环境,但是我不知道其他方式(例如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