根据端口号获取服务名

shell截取第四列后面的数值 # ss -ntl State Recv-Q Send-Q Local Address:Port Peer Address:Port

shell截取第四列后面的数值

# ss -ntl 

State       Recv-Q Send-Q              Local Address:Port         Peer Address:Port                                                                                 

LISTEN      0      128                 :5673                      :*   

#获取第四列,再获取最后一列,去重排序

ss -ntl | awk 'NR>1 {print $4}' | awk -F ':' '{print $NF}'  | sort -nu

#根据端口号获取服务名

#!/bin/bash

# 获取所有监听的 TCP 端口(兼容 IPv4/IPv6)
ports=$(ss -ntl | awk 'NR>1 {split($4, a, /:/); print a[length(a)]}' | sort -nu)

echo "PORT     SERVICE"

# 遍历每个端口并获取服务名称
for port in $ports; do
    # 使用 lsof 查找监听该端口的服务(需 root 权限)
    service=$(sudo lsof -i :"$port" -sTCP:LISTEN -P -n 2>/dev/null | \
              awk 'NR>1 {print $1}' | \
              sort -u | \
              paste -sd, -)

    # 处理未找到服务的情况
    [[ -z "$service" ]] && service="unknown"

    # 格式化输出
    printf "%-8s %s\n" "$port" "$service"
done

命令解析

命令拆解分析:
‌ss -ntl‌

ss:Socket Statistics,查看套接字信息
-n:以数字形式显示地址/端口(不解析域名和服务名)
-t:仅显示TCP套接字
-l:仅显示监听状态(LISTEN)的套接字

将ss的输出传递给awk处理
‌awk 'NR>1 {split($4, a, /:/); print a[length(a)]}'‌

NR>1:跳过第一行标题(处理第2行及以后)
split($4, a, /:/):
$4:第4列(本地地址:端口,如0.0.0.0:22或[::]:80)
使用冒号 : 分割字符串到数组 a
‌示例分割结果‌:
0.0.0.0:22 → ["0.0.0.0", "22"]
[::]:80 → ["[","","", "80"](IPv6地址特殊处理)
print a[length(a)]:
length(a):数组长度(最后一个元素的索引)
打印数组最后一个元素(即端口号)

命令解析

1. ‌lsof -i :"$port" -sTCP:LISTEN -P -n‌
-i :$port:筛选监听指定端口的网络连接
-sTCP:LISTEN:仅显示处于 ‌LISTEN 状态‌ 的TCP连接
-P:禁用端口号到服务名的解析(直接显示数字端口)
-n:禁用IP地址到域名的解析(直接显示数字IP)
2>/dev/null:忽略错误输出(如权限不足的警告)

2. ‌awk 'NR>1 {print $1}'‌
NR>1:跳过表头行(第一行)7
print $1:提取第一列数据(即进程名称 COMMAND 列)

3. ‌sort -u‌
对进程名称去重排序,避免重复项8
4. ‌paste -sd, -‌
将多行结果合并为单行,并用逗号分隔

LICENSED UNDER CC BY-NC-SA 4.0
Comment