![.pid 文件是否可靠地确定某个进程是否正在运行?](https://linux22.com/image/506513/.pid%20%E6%96%87%E4%BB%B6%E6%98%AF%E5%90%A6%E5%8F%AF%E9%9D%A0%E5%9C%B0%E7%A1%AE%E5%AE%9A%E6%9F%90%E4%B8%AA%E8%BF%9B%E7%A8%8B%E6%98%AF%E5%90%A6%E6%AD%A3%E5%9C%A8%E8%BF%90%E8%A1%8C%EF%BC%9F.png)
许多程序(例如 sshd)在 /var/run/ 中创建包含其进程 ID 的 .pid 文件。这些文件是否可靠地确定进程是否正在运行?我猜这些文件是由进程手动创建的,因此如果程序崩溃,它们仍会保留在文件系统中。
答案1
简单来说,不:一个进程(例如守护进程)可能崩溃并且没有时间清除其.pid 文件。
一种更确定程序状态的技术:使用显式通信通道(如套接字)。将套接字端口写入文件中并让进程supervisor
查找它。
您还可以使用 Linux 上的 DBus 服务:注册一个特定的名称,并让您的主管进程(无论您如何称呼它)检查该名称。
有很多种技术。
要记住一件事:管理 PID 文件不是操作系统的责任。
答案2
Jldupont 的说法是正确的,.pid 文件是不可靠的用于确定进程是否正在运行,因为在发生崩溃时可能不会删除该文件。
除了竞争条件之外,我经常使用程序包当我需要知道某个进程是否正在运行时。如果我觉得有必要,我可以将输出与 .pid 文件进行交叉引用。
答案3
包含进程 ID 的文件无法可靠地确定进程是否正在运行。它只是一个可靠的来源,可以找出进程的最后一个给定进程 ID。
当您获得进程 ID 时,您必须做进一步检查,看看该进程是否真的在运行。
以下是一个例子:
#!/usr/bin/env sh
file="/var/run/sshd.pid"
processid=$(cat /var/run/sshd.pid)
if [ ! -f ${file} ]; then
echo "File does not exists: ${file}"
exit 1
fi
if [ ! -r ${file} ]; then
echo "Insufficient file persmissons: ${file}"
exit 1
fi
psoutput=$(ps -p ${processid} -o comm=)
if [ $? == 0 ];then
if [ ${psoutput} == "sshd" ]; then
echo "sshd process is realy running with process id ${processid}"
exit 0
else
echo "given process id ${processid} is not sshd: ${psoutput}"
exit 1
fi
else
echo "there is no process runing with process id ${processid}"
exit 0
fi
pgrep 是一个不错的命令,但当你有多个实例运行时,你会遇到麻烦。例如,当你在端口 TCP/22 上运行常规 sshd,而在端口 TCP/2222 上运行另一个 sshd 时,pgrep 在搜索时会提供两个进程 IDsshd...当普通 sshd 的 pid 在 /var/run/sshd.pid 中,而另一个 sshd 的 pid 在 /var/run/sshd-other.pid 中时,您可以清楚地区分各个进程。
我不要建议只使用附言,通过一个或多个管道grep和grep -v尝试过滤掉所有你不感兴趣的东西……这有点像使用
find . | grep myfile
确定文件是否存在。
答案4
Jldupont 是正确的。
但是,您可以向该进程发送 0 信号(kill -s 0 pid)以查看该进程是否仍然活动(假设您有权发送此类信号 - 一般来说,只有进程的所有者才可以向其发送信号)。