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, -
将多行结果合并为单行,并用逗号分隔