You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

无法通过awk从fuser输出提取端口占用PID的技术求助

解决fuser提取端口占用PID失败的问题

最近我遇到个小麻烦:想提取占用9092/tcp端口的进程ID,用fuser直接查能得到正确结果:

$ fuser 9092/tcp
9092/tcp: 5920

但想用awk分割冒号提取PID时,结果却不对:

$ fuser 9092/tcp | awk -F: '{print $2}'
9092/tcp:

本来想把提取到的PID用来执行ls -l /proc/<PID>/exe,写成了:

ls -l /proc/$(fuser 9092/tcp | awk -F: '{print $2}')/exe

结果自然没法正常运行。

我的环境工具版本:

  • bash:GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu)
  • fuser:fuser (PSmisc) 22.20

问题根源

其实是PSmisc版本的fuser输出流向搞的鬼:它默认把带端口号的提示文本输出到标准错误(stderr),而真正的PID是输出到标准输出(stdout)。所以当你用管道给awk时,awk读到的是空内容(或者如果你的环境里输出流向不同,那就是分隔符没选对)。

几种解决方案

方案1:直接捕获fuser的标准输出(最简洁)

把stderr的提示信息重定向到/dev/null,直接拿到PID:

PID=$(fuser 9092/tcp 2>/dev/null)
ls -l /proc/$PID/exe

或者写成一行:

ls -l /proc/$(fuser 9092/tcp 2>/dev/null)/exe

方案2:调整awk的分隔符(针对输出整行到stdout的情况)

如果你的fuser确实把9092/tcp: 5920整行输出到stdout,那可以把分隔符设为冒号加空格,或者直接按空格分割:
: 分割:

ls -l /proc/$(fuser 9092/tcp | awk -F': ' '{print $2}')/exe

按空格分割(更简单):

ls -l /proc/$(fuser 9092/tcp | awk '{print $2}')/exe

方案3:换用lsof(更直观的工具)

如果觉得fuser的逻辑太绕,用lsof来提取PID会更直接:

ls -l /proc/$(lsof -i :9092 -t)/exe

-i :9092指定查找9092端口的进程,-t选项让lsof只输出PID,省心不少。

内容的提问来源于stack exchange,提问作者Ibrahim Quraish

火山引擎 最新活动