Shell实战之Linux性能统计

常用性能命令

问题:统计一个进程的实时cpu数据需要用到哪个命令?

[root@shell.ceshiren.com ~]$ ps -ef | head -10
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 7月02 ?       00:01:00 /usr/lib/systemd/systemd --switched-root --system --deserialize 21
root         2     0  0 7月02 ?       00:00:00 [kthreadd]
root         3     2  0 7月02 ?       00:00:01 [ksoftirqd/0]
root         5     2  0 7月02 ?       00:00:00 [kworker/0:0H]
root         7     2  0 7月02 ?       00:00:02 [migration/0]
root         8     2  0 7月02 ?       00:00:00 [rcu_bh]
root         9     2  0 7月02 ?       00:00:49 [rcu_sched]
root        10     2  0 7月02 ?       00:00:00 [watchdog/0]
root        11     2  0 7月02 ?       00:00:00 [watchdog/1]


[root@shell.ceshiren.com ~]$ ps aux |head -10
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.1  43884  4232 ?        Ss   7月02   1:00 /usr/lib/systemd/systemd --switched-root --system --deserialize 21
root         2  0.0  0.0      0     0 ?        S    7月02   0:00 [kthreadd]
root         3  0.0  0.0      0     0 ?        S    7月02   0:01 [ksoftirqd/0]
root         5  0.0  0.0      0     0 ?        S<   7月02   0:00 [kworker/0:0H]
root         7  0.0  0.0      0     0 ?        S    7月02   0:02 [migration/0]
root         8  0.0  0.0      0     0 ?        S    7月02   0:00 [rcu_bh]
root         9  0.0  0.0      0     0 ?        S    7月02   0:49 [rcu_sched]
root        10  0.0  0.0      0     0 ?        S    7月02   0:00 [watchdog/0]
root        11  0.0  0.0      0     0 ?        S    7月02   0:00 [watchdog/1]

封装自己的ps命令

ps_ex ()
{
    ps -o uname,pid,ppid,thcount,ni,pri,psr,pcpu,pmem,rss,vsz,sz,start_time,time,comm,c,command,args "$@"
}

网络命令

作业1 统计aliyundun的性能

perf_get(){
/#todo: 输出20s内某个进程的每秒的cpu和mem,并最后空出一行统计平均性能
}

perf_get pid_or_name
cpu mem
3 4
2 6
2 2
3 4

10 2

5.5 3.5

#shell自带的type命令输出
perf_get ()
{
    top -b -d 1 -n 20 | grep --color=auto --line-buffered -i yundun$ | awk 'BEGIN{print "cpu","mem"}{cpu+=$9;mem+=$10;print $9,$10}END{print "";print cpu/NR,mem/NR}'
}

#vs code+shell format
perf_get() {
    top -b -d 1 -n 20 |
        grep --color=auto --line-buffered -i yundun$ |
        awk '
    BEGIN{print "cpu","mem"}
    {cpu+=$9;mem+=$10;print $9,$10}
    END{print "";print cpu/NR,mem/NR}
    '
}

网络命令

[root@shell.ceshiren.com ~]$ netstat -tlnp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN      2565/./src/redis-se
tcp        0      0 127.0.0.1:9101          0.0.0.0:*               LISTEN      11880/node_exporter
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      2285/sshd
tcp6       0      0 :::6379                 :::*                    LISTEN      2565/./src/redis-se


[root@shell.ceshiren.com ~]$ netstat -tnp |head -10
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 172.19.147.8:22         171.44.150.69:18878     ESTABLISHED 22177/sshd: 7626236
tcp        0      0 172.19.147.8:22         27.38.236.18:61475      ESTABLISHED 16215/sshd: 4485488
tcp        0      0 172.19.147.8:22         120.244.154.214:11869   ESTABLISHED 9077/sshd: 61206233
tcp        0      0 172.19.147.8:22         111.196.246.197:15543   ESTABLISHED 21596/sshd: 0672644
tcp        0      0 172.19.147.8:22         116.76.26.4:7307        ESTABLISHED 4211/sshd: 17099360
tcp        0      0 172.19.147.8:22         125.120.13.159:53060    ESTABLISHED 19902/sshd: 8871942
tcp        0      0 172.19.147.8:22         223.104.211.251:55464   ESTABLISHED 6177/sshd: 17772451

作业2 统计连接网络链接情况

connection_summary(){
#todo: 链接所有的端口和对应的tcp连接状态,找出他们的连接总数吧
}

connection_summary
22 ESTABLISHED 100
22 CLOSED 3
7777 ESTABLISHED 20

答案

connection_summary() {
    netstat -tn |
        awk 'NR>2{print $4,$6}' |
        awk -F: '{print $2}' |
        sort | uniq -c | sort -nr |
        awk '{print $2"\t"$3"\t"$1}'
}

bash编程

作业3 抽奖脚本

100个人,每个人给一个骰子,掷骰子>3的点认为是通过的,否则淘汰。第一轮选出的人进入第二轮继续比赛,直至选出最终冠军。如果没有选出一个,可以复活上一轮的选手

lucky(){

}

seq 1 100 | lucky

第一轮: 1 2 3 5 88 99 .100
第二轮: 1 3 88 
第三轮: 3 88
第四轮: 3 88
第五轮: 
第六轮:  3 88
第七轮: 88

答案

#seq 1 100 | lucky
#seq 1 100 | xargs | lucky
lucky() {
    #需要给默认值,不然用于数组的时候,会默认有一个初始元素
    local all=() sub_temp=() sub=() index=0

    #多行模式支持选手名字带有空格
    while read line; do
        all+=("$line")
    done
    #单行的时候,默认空格区分每个选手
    ((${#all[@]} == 1)) && all=($all)
    #用于数据处理,不影响原来的all
    sub=("${all[@]}")

    while true; do
        echo "index=$index count=${#sub[@]} sub=${sub[@]}"
        ((index++))
        #用于复活上一轮的种子
        sub_temp=(${sub[@]})

        for i in "${!sub[@]}"; do
            ((RANDOM % 6 + 1 > 3)) || unset sub[$i]
        done

        ((${#sub[@]} == 1)) && {
            echo
            echo winner=${sub[@]}
            break
        }
        #复活上一轮
        ((${#sub[@]} == 0)) && { sub=(${sub_temp[@]}); }
    done
}

1 个赞
top  -b -d 1 -n 20 |grep -i --line-buffered "Aliyundun"|awk '{print $9,$10}{ num += $9;sum += $10} END {print num/NR,sum/NR}'
top -b -d 1 -n 20 | grep --line-buffered -iw aliyundun | awk 'BEGIN{print "cpu","mem";a=0;b=0}{a+=$9,b+=$10;print $9,$10}END{print "\n"; print a/ NR, b/NR}'
perf_get(){
    top -p 22985 -b -d 1 -n 20 | awk '{print $1,$7}'| awk '{ avg += $(NF)END{print avg/NR}}'
}

perf_get(){
/#todo: 输出20s内某个进程的每秒的cpu和mem,并最后空出一行统计平均性能
`top -b -p -n 20 -d 1| grep  -i  Aliyundun --line-buffered | awk 'BEGIN{print "CPU%","MEM%"}{print $9,$10}{cpu+=$9;mem+=$10}END{print "------";print cpu/NR,mem/NR}'`
}

$ top -b -d 1 -n 20 | grep --line-buffered -i AliYunDun | awk ‘{print $9,$10}’

top -p 22985 -b -d 1 -n 20 | grep --line-buffered -i aliyun | awk '{print $9,$10}BEGIN{a=0,b=0}{a+=S9;b+=$10}END{print a/NR,b/NR}'
perf_get() {

    top -b -d 1 -n 20 | grep --line-buffered -i aliyundun$ | awk '{print $9,$10}BEGIN{a=0;b=0}{a+=$9;b+=$10}END{print a/NR,b/NR}'

}
1 个赞
perf_get () 
{ 
    top -b -d 1 -n 20 | grep --color=auto -i --line-buffer AliYunDun$ | awk 'BEGIN{print "cpu mem"}{print $9,$10}{sum_cpu+=$9;sum_mem+=$10}END{print "";print sum_cpu/NR,sum_mem/NR}'
}

top -p 22985 -b -d 1 -n 20 |grep -i aliyun --line-buffered |awk ‘{printf $6" "$9}’|awk ‘{ memsum += $1; sum+=$2} END {print "mem_average = " memsum/NR;print "cpu_average = " sum/NR }’

top -b -p 22985 -n 20 -d 1| grep --line-buffered -i Aliyun| awk '{print $9 $10} {a+=$9;b+=$10}END{print a/NR,b/NR}'

‘’’
top -b -p 22985 -n 20 -d 1 | grep 22985 --line-buffered | awk 'BEGIN{print "CPU%","MEM%"}{print $9,$10}{cpu+=$9;mem+=$10}END{print "------";print cpu/NR,mem/NR}'
‘’’

echo "%CPU,%MEM" > cpu_test.csv
pid=1 #Can be change by yourself
while true
do
top -bn1 -n 1 -p $pid | tail -1 | awk '{ print 9,10 }' | sed 's/ /,/' >> cpu_test.csv
sleep 2 #delay time
done
perf_get(){
    top -b -d 1 -n 20 | grep --line-buffered -iw aliyundun | awk 'BEGIN{print "cup mem"}{a+=$9;b+=$10;print $9,$10}END{print "";print a/NR, b/NR}'
}
perf_get() {
    top -b -d 1 -n 20 | grep --line-buffered -i aliyun | awk '{print $9,$10; cpu+=$9; mem+=$10}END{print ""; print cpu/NR,mem/NR}'
}

perf_get() {
top -b -d 1 -n 20 | grep -i --line-buffer aliyundun$ | awk ‘BEGIN{print “perf_get:\npname\tcpu\tmem\n”}{cpu +=$9;mem +=$10;i++;avg_cpu =cpu/NR;avg_mem=mem/NR;print $12,cpu,"\t",mem}END{print “\navg:\t”,avg_cpu," ",avg_mem}’
}

top -b -d 1 -n 5|grep -line-buffered -i yundun$|awk ‘{cpu+=$9;mem+=$10;print $9,$10;print cpu/NR,mem/NR}’
为啥我这总提示我没有yundun这个目录或文件

老师,批处理这个怎么理解呢?

perf_get(){
top -b d 1 -n 5 | grep --line-buffer AliYunDun | awk ‘BEGIN{print “CPU”,“MEM”} {cpu+=$9;mem+=$10;print $9,$10}END{print cpu/NR,mem/NR}’
}

cpu和mem变量最后计算时为啥不加$ ??

awk 命令中变量的赋值和引用不需要加$