1. 格式化某些 /proc 文件輸出
Linux下有些 proc 文件的輸出內容確實沒法看,比如/proc/net/snmp
的輸出如下:
[root@localhost ~]# cat /proc/net/snmp
Ip: Forwarding DefaultTTL InReceives InHdrErrors InAddrErrors ForwDatagrams InUnknownProtos InDiscards InDelivers OutRequests OutDiscards OutNoRoutes ReasmTimeout ReasmReqds ReasmOKs ReasmFails FragOKs FragFails FragCreates
Ip: 2 64 1112736 0 0 0 0 0 1112733 1112545 0 36 0 0 0 0 0 0 0
Icmp: InMsgs InErrors InCsumErrors InDestUnreachs InTimeExcds InParmProbs InSrcQuenchs InRedirects InEchos InEchoReps InTimestamps InTimestampReps InAddrMasks InAddrMaskReps OutMsgs OutErrors OutDestUnreachs OutTimeExcds OutParmProbs OutSrcQuenchs OutRedirects OutEchos OutEchoReps OutTimestamps OutTimestampReps OutAddrMasks OutAddrMaskReps
Icmp: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Tcp: RtoAlgorithm RtoMin RtoMax MaxConn ActiveOpens PassiveOpens AttemptFails EstabResets CurrEstab InSegs OutSegs RetransSegs InErrs OutRsts InCsumErrors
Tcp: 1 200 120000 -1 2207 2204 4 598 3803 1112646 1112462 0 0 303 0
Udp: InDatagrams NoPorts InErrors OutDatagrams RcvbufErrors SndbufErrors InCsumErrors IgnoredMulti
Udp: 176 0 0 91 0 0 0 0
UdpLite: InDatagrams NoPorts InErrors OutDatagrams RcvbufErrors SndbufErrors InCsumErrors IgnoredMulti
UdpLite: 0 0 0 0 0 0 0 0
第一行是字段,第二行是字段的值。這些輸出每一行包含的字段太多,字段和值又沒對齊,看着太費勁,遂用awk
命令格式化下這類輸出,以後方便查看。
awk
命令如下:
awk '{\
if (NR % 2 == 0) print $1;\
for(i = 2; i <= NF; i++) {\
if (NR % 2 ) \
count[i] = $i;\
else if ($i > 0) \
printf(" %-28s:%d\n",count[i], $i);\
}\
}' \
/proc/net/snmp
格式化後的效果如下:
Ip:
Forwarding 2
DefaultTTL 64
InReceives 2252593
InDelivers 2252590
OutRequests 2252398
OutNoRoutes 36
Icmp:
Tcp:
RtoAlgorithm 1
RtoMin 200
RtoMax 120000
ActiveOpens 3807
PassiveOpens 3804
AttemptFails 4
EstabResets 598
CurrEstab 7003
InSegs 2252503
OutSegs 2252315
OutRsts 303
Udp:
InDatagrams 176
OutDatagrams 91
UdpLite:
上述命令按格式打印非0值的字段和值。該命令也適合/proc/net/netstat
文件。
結合watch
命令就能定時得查看這些值的變化,命令如下:
watch -n 1 "awk '{if (NR % 2 == 0) print \$1;for(i = 2; i <= NF; i++) {if (NR % 2 ) count[i]=\$i; else if (\$i > 0 ) printf(\" %-28s%d\n\",count[i], \$i);}}' /proc/net/netstat"
更進一步,watch
命令只能看到某個時間點的數值統計,如果想查看每秒鐘數值的變化,就不那麼容易了,我花了些時間寫了如下命令來實現這個效果:
echo '' > tmp.txt; \
for((i = 1; ; i++)); do \
awk '{for(i = 2; i <= NF; i++) {if (NR % 2 ) count[i] = $i; else if ($i > 0 ) print count[i], $i;}}' \
/proc/net/snmp /proc/net/netstat >> tmp.txt; \
if [ `expr $i % 2` == 0 ]; then \
printf "\033c"; \
awk '{if (a[$1]) {if ($2 != a[$1]) printf("%-28s%d\n", $1, $2 - a[$1])} else a[$1] = $2;}' tmp.txt; \
echo '' > tmp.txt;\
else \
sleep 1;\
fi; \
done
這個命令會每秒鐘輸出/proc/net/snmp
和 /proc/net/netstat
文件中數值的變化,輸出格式如下:
InReceives 76931
InDelivers 76931
OutRequests 76931
InMsgs 4
InEchos 2
InEchoReps 2
OutMsgs 4
OutEchos 2
OutEchoReps 2
InType0 2
InType8 2
OutType0 2
OutType8 2
ActiveOpens 200
PassiveOpens 166
EstabResets 200
CurrEstab 132
InSegs 76927
OutSegs 76927
OutRsts 100
DelayedACKs 1114
DelayedACKLocked 2
ListenOverflows 34
ListenDrops 34
TCPHPHits 15774
TCPPureAcks 339
TCPHPAcks 35402
TCPAbortOnClose 100
TCPOrigDataSent 41348
InOctets 46293624
OutOctets 46300484
InNoECTPkts 77482