我需要测试是否有任何进程正在侦听特定套接字;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
),您可以使用ss
:lsof
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
这里有两件重要的事情需要注意:
Unix套接字的真实地址是
device,inode
数字元组,不是路径名。如果套接字文件是搬家了,无论哪个服务器正在侦听它,都可以通过新路径进行访问。如果套接字文件是已删除,另一台服务器可以侦听同一路径(这就是为什么 Unix 套接字的目录权限很重要,安全方面)。lsof
无法处理这个问题,并且可能返回不完整/不正确的数据。ss
本身就有问题,并且因为unix_diag
netlink 接口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
丑陋但实用。