我想定期观察套接字状态,因此需要通过命令检查套接字状态。
目前,我列出了所有侦听套接字并按ss
进行过滤grep
。
ss -l | grep -q /run/php/php7.0-fpm.sock
有没有更好的方法来检查套接字的状态?
答案1
您可以通过尝试连接来获取一些信息,在断开连接之前不传递任何内容也不接受任何内容。
socat -u OPEN:/dev/null UNIX-CONNECT:/run/php/php7.0-fpm.sock
至少有四种可能的结果:
如果套接字不存在,则错误将为
No such file or directory
,退出状态将为1
。如果您没有对套接字的写访问权限,则错误将为
Permission denied
,退出状态将为1
。在这种情况下,您无法判断是否有进程正在监听。如果您对套接字具有写访问权限并且没有监听进程,则错误将为
Connection refused
,退出状态将为1
。如果您对套接字具有写访问权限并且有进程正在侦听,则将建立连接。该命令不会发送任何内容(如
cat /dev/null
),也不会尝试接收任何内容(因为-u
),因此它几乎会立即退出。退出状态将为0
。连接建立了,短暂但仍然。侦听进程可以配置为仅接受一个连接,为其提供服务并退出;或一次接受一个连接。在这种情况下,探测连接将达到极限;这是不希望的。然而,在实践中,我希望绝大多数监听进程能够为多个连接提供服务,并优雅地处理无情断开连接的客户端。
笔记:
- 您需要解析 stderr 以区分生成退出状态的情况
1
。 - 该过程没有告诉任何进程正在侦听。
答案2
您可以通过设备和 inode 号进行匹配:
ss -elx | grep -w "$(stat -c 'ino:%i dev:0/%d' /run/php/php7.0-fpm.sock)"
如果您只关心其退出状态,请提供-q
选项(0 = 成功,如果有进程正在侦听该文件)。grep
查看相关回答以及从那里链接的一个解释和陷阱,特别是关于 . 返回的设备编号的错误格式的部分ss
。
尝试连接到套接字以确定是否有东西正在监听它就像咬某人看他们是否还活着;-)
答案3
如果您只是想检查端口是否打开,我建议使用 telnet,如下所示:
telnet localhost <port>
然而,您似乎想要编写脚本并定期检查。除了上面的优秀答案之外,这里还有一个关于如何做到这一点的示例。
我通过以下方式确认 SE 帖子楚斯并添加一些有关其工作原理的信息。
host=localhost; port=222
r=$(bash -c 'exec 3<> /dev/tcp/'$host'/'$port';echo $?' 2>/dev/null)
if [ "$r" = "0" ]; then
echo "$host $port is open";
else
echo "$host $port is closed";
fi
这是线条解释了:
bash -c
在空环境中执行命令。exec 3<> /dev/tcp/'$host'/'$port'
打开 /dev/tcp/'$host'/'$port' 进行读写。echo $?
记录最后一个命令的退出代码(0或非零);变量“r”获取该值。
现在我们有了变量 $r,它可以是 0(开)或非零(闭)。在此基础上,您可以执行诸如回显结果、写入日志文件或通过电子邮件发送输出之类的操作。您可以将其作为 cron 作业运行。
HTH。