如何解决sockstat -l输出中字段过长导致的列碰撞问题?
解决sockstat -l输出中命令名与PID碰撞/错误拆分的问题
我之前也碰到过sockstat输出列错位的糟心事——当用户名或命令名太长时,COMMAND和PID会粘在一起;更头疼的是命令名本身带数字时,还会被错误拆分成命令名+数字,导致整个列序混乱。下面分享一个用awk写的处理脚本,能搞定这两种情况:
处理脚本
NR == 1 { print; next } { # 锁定最后三列:PROTO、LOCAL ADDRESS、FOREIGN ADDRESS,这三列格式固定不会乱 proto = $(NF-2) local_addr = $(NF-1) foreign_addr = $NF fd = $(NF-3) pid = $(NF-4) user = $1 cmd = $2 # 处理命令名被错误拆分的情况(比如nrpe3被拆成nrpe和3) if (NF >= 7 && $(NF-5) ~ /^[0-9]+$/ && pid ~ /^[0-9]+$/ && $(NF-5) < pid) { cmd = cmd $(NF-5) pid = $4 fd = $5 proto = $6 local_addr = $7 foreign_addr = $8 } # 处理命令名与PID粘在一起的情况(比如apacheexp2356是apacheexp+2356) else if (pid !~ /^[0-9]+$/ && NF == 6) { if ($2 ~ /([0-9]+)$/) { pid = substr($2, RSTART, RLENGTH) cmd = substr($2, 1, RSTART-1) } } # 格式化输出,保证列对齐 printf "%-12s %-10s %5d %3d %-6s %-16s %s\n", user, cmd, pid, fd, proto, local_addr, foreign_addr }
脚本工作原理
- 表头处理:第一行是表头,直接输出不做处理。
- 固定列定位:不管前面的列怎么乱,最后三列(PROTO、本地地址、外部地址)的格式是固定的,先锁定这三列的位置。
- 错误拆分修复:如果列数大于等于7,且倒数第5列是数字、倒数第4列也是数字,并且倒数第5列的数值远小于倒数第4列(符合PID通常比FD大的规律),就判断是命令名被错误拆分了,把第2列和倒数第5列合并成正确的命令名,再重新定位PID、FD等列。
- 粘列拆分修复:如果倒数第4列不是数字且列数为6,说明命令名和PID粘在了第2列,用正则提取第2列末尾的数字作为PID,剩下的部分作为命令名。
- 格式化输出:用printf对齐各列,让输出看起来更整齐。
测试效果
输入1(命令名与PID粘在一起)
USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN ADDRESS xxxxxxxxxx apacheexp2356 3 tcp46 *:9117 *:* root ntpd 819 20 udp6 *:123 *:*
输出1
USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN ADDRESS xxxxxxxxxx apacheexp 2356 3 tcp46 *:9117 *:* root ntpd 819 20 udp6 *:123 *:*
输入2(命令名带数字被错误拆分)
USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN ADDRESS nagios nrpe 3 2222 4 tcp6 *:5666 *:*
输出2
USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN ADDRESS nagios nrpe3 2222 4 tcp6 *:5666 *:*
内容的提问来源于stack exchange,提问作者pdna
相关产品推荐
相关产品推荐

