linux排查端口与进程关系需分场景:查“进程占哪些端口”用ps配合ss或lsof -i -c;查“端口被哪个pid占用”用sudo ss -tulnp | grep :端口或sudo lsof -i :端口 -pn;注意权限、状态过滤及多实例区分。

直接查不到“某个进程的PID端口号”——PID和端口号是两个独立概念,你要的是“某个进程占用了哪些端口”,或者“某个端口被哪个PID占用”。下面分场景说清楚怎么做、为什么这么写、容易错在哪。
用 ps + netstat 或 ss 查进程对应端口
这是最常踩坑的组合:先用 ps 找到进程 PID,再用网络命令反查它监听的端口。但注意——ps 本身不显示端口信息,必须配合网络工具。
-
ps -ef | grep nginx得到 PID(比如9836),但这只是进程 ID,不带端口 - 接着必须用
sudo netstat -tulnp | grep 9836或更推荐的sudo ss -tulnp | grep 9836,才能看到该 PID 对应的0.0.0.0:8081这类监听项 - 别漏
sudo:没权限时-p参数会失效,输出里看不到 PID/进程名 -
ss比netstat更快、更现代,且默认不依赖net-tools包;如果系统没装lsof,优先用ss
用 lsof -i 直接按进程名查端口(支持模糊匹配)
lsof 的优势在于能跳过 PID 中转,直接从进程名出发查端口,适合你只知道服务名(如 java、python3)但不确定 PID 的场景。
-
sudo lsof -i -c java列出所有java开头的进程占用的网络连接(含端口) -
sudo lsof -i -c python3同理,但注意:-c 只匹配COMMAND列的前 15 字符,长命令名可能截断 - 若要匹配完整启动命令(比如含路径或参数),改用
sudo lsof -i | grep -E "python3.*myapp.py",或搭配pgrep -f先取 PID 再查 - 常见错误:
lsof -i :8080是查端口找进程,不是查进程找端口——方向反了
端口查 PID 时 LISTEN 状态没显示?加 -Pn 参数
有些端口处于 TIME_WAIT、ESTABLISHED 等非监听状态,lsof -i:端口号 默认只显示 LISTEN,容易漏掉真实占用者。
- 查所有状态的连接:用
sudo lsof -i:8080 -Pn,其中-P禁用端口名解析(避免卡 DNS),-n禁用 IP 解析(提速) -
sudo ss -tunp | grep :8080同样能覆盖非 LISTEN 状态,且无需额外参数 - 如果
lsof输出为空但你知道端口确实在用,大概率是状态不匹配,别急着换工具,先加-Pn
拿到 PID 后怎么确认是不是你要的那个进程?
多个同名进程(比如 5 个 java)共存时,光看 PID/COMMAND 不够,得看启动命令和工作目录。
- 查完整启动命令:
ps -p 1234 -o cmd=或cat /proc/1234/cmdline | tr '\0' ' ' - 查当前工作目录:
readlink /proc/1234/cwd - 查打开的文件/配置:
ls -l /proc/1234/fd/(尤其关注 fd 0/1/2 和配置文件路径) - 别只信
COMMAND列——它可能只是java,实际跑的是不同 JAR 包,必须看cmdline或cwd
真正难的不是查到 PID 或端口,而是确认那个 PID 对应的就是你关心的服务实例。同一进程名下多个实例、容器环境中的 PID 命名空间隔离、systemd 管理的子进程隐藏——这些都会让简单命令返回误导性结果。动手前,先想清楚:你要 kill 的是哪个?重启的是哪一例?日志路径在哪?这些比“查到端口”重要得多。











