在测试套接字时如何让 lsof 停止抱怨?

在测试套接字时如何让 lsof 停止抱怨?

我需要测试是否有任何进程正在侦听特定套接字;fuser目标系统上不存在,但lsof确实存在。我运行这个命令:

lsof -tU /path/to/socket

它列出了侦听器的 PID,这很好,但lsof退出时状态为1。我更改命令看看出了什么问题:

lsof -tUV /path/to/socket

它再次列出了 PID,但还添加了以下内容:

lsof:没有文件使用位于:/path/to/socket

有什么方法可以抑制“文件使用”的额外检查,以便它在出现0时退出在套接字上找到监听器?我浏览了手册页,但找不到我想要的东西。我想像这样明智地使用它:

sock=/path/to/socket
if [[ ! -S $sock ]] || ! lsof -tU $sock &>/dev/null; then
    # task to activate socket listener
fi

答案1

如果您使用的系统具有最新版本ss(例如Debian 10 上的版本iproute2-ss190107),您可以使用sslsof

sock=/path/to/socket
ino=$(stat -c 'ino:%i' "$sock") && ss -elx | grep -w "$ino"

sock=/path/to/socket
if ino=$(stat -c 'ino:%i' "$sock") && ss -elx | grep -qw "$ino"
then
   # yeah, somebody's listening on $sock
fi

这里有两件重要的事情需要注意:

  1. Unix套接字的真实地址是device,inode数字元组,不是路径名。如果套接字文件是搬家了,无论哪个服务器正在侦听它,都可以通过新路径进行访问。如果套接字文件是已删除,另一台服务器可以侦听同一路径(这就是为什么 Unix 套接字的目录权限很重要,安全方面)。lsof无法处理这个问题,并且可能返回不完整/不正确的数据。

  2. ss本身就有问题,并且因为unix_diagnetlink 接口ss正在使用 Linux 内核内部使用的格式返回设备号,但ss假设它采用系统调用接口(如 )使用的格式stat(2),因此上面输出dev:中的条目ss -elx将被管理。然而,对其进行修复可能是不明智的,因为有一天他们可能会决定修复它。因此,唯一的做法就是将其dev:视为纯粹的垃圾,并承受两个套接字文件具有相同 inode 但位于不同文件系统上的风险,上面的测试无法处理


如果上述所有内容对您来说都不重要,您可以做同样糟糕的事情lsof(匹配套接字首先绑定到的路径):

sock=/path/to/socket
ss -elx | grep " $sock "

它也应该适用于像 Centos 7 这样的旧系统。至少这确实有一个优点,即只列出聆听插座;-)

答案2

我最终做的是这样的:

if ! [[ -S $SSH_AUTH_SOCK && -n "`ss -xa 2>/dev/null | grep -F $SSH_AUTH_SOCK 2>/dev/null`" ]]; then
    # task to activate socket listener
fi

丑陋但实用。

相关内容