我正在使用 CentOS 7。我想获取在端口 3000 上运行的进程的 PID(如果存在)。我想获取此 PID,以便将其保存到 shell 脚本中的变量中。到目前为止我有
[rails@server proddir]$ sudo ss -lptn 'sport = :3000'
State Recv-Q Send-Q Local Address:Port Peer Address:Port
Cannot open netlink socket: Protocol not supported
LISTEN 0 0 *:3000 *:* users:(("ruby",pid=4861,fd=7),("ruby",pid=4857,fd=7),("ruby",pid=4855,fd=7),("ruby",pid=4851,fd=7),("ruby",pid=4843,fd=7))
但我无法弄清楚如何在没有所有这些额外信息的情况下单独隔离 PID。
另一种可能的解决方案:
例如:
尝试这个:
(需要
psmisc
包)请注意,这仅在由用户 root 运行时才可靠。其他用户只能希望找到以相同用户运行的进程。
此处以示例对仅 root 访问进行了无聊的解释。
无论使用什么方法(fuser、ss、lsof、...),它们最终都会将可用的进程描述符列表与可用的网络连接列表相匹配(例如,对于 tcp,它在 中可用
/proc/net/tcp
)。例如,尝试使用端口
22/tcp
(22 = 0x0016)获取 pid 最终会进行这种比较:来自
/proc/net/tcp
:0: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 141408 1 000000000a9ac1b5 100 0 0 10 0
和:
dr-x------. 2 root root 0 May 14 17:59 /proc/358/fd lrwx------. 1 root root 64 May 14 17:59 /proc/358/fd/3 -> socket:[141408]
由于此 fd 描述符仅对其用户(在此示例中恰好是 root)或 root 可用,因此只有该用户或 root 可以发现 pid 为 358。
虽然
lsof
's-t
是获取 PID 的最简单方法,但lsof
也可以使用以下-F
选项选择其他字段:使用这样的输出(请注意,始终打印 PID 和文件描述符):
因此,如果您想要进程组 ID 而不是 PID,您可以这样做:
这正是您需要的
警告:我只能在 RedHat 上进行测试。
应该可以
netstat
吗?-n用于数字端口
-l用于侦听端口
-p用于查看 PID
您可以使用--inet或--inet6开关来告诉
netstat
您分别只查找 IPv4 或 IPv6,否则您可能会得到两个结果。或者,您可以告诉
awk
只打印一次在
awk
我们只是使用 PID/program 的输出中的“ / ”netstat
作为分隔符。