linux和bash实战--最后面5个实战例子没懂

脚本与函数

花括号括起来的一段shell命令

#错误写法
[root@shell.ceshiren.com ~]$ cpu_mem(){top -b  -n 1 -d 1 | grep -i aliyundun$ | awk '{print $9,$10}'; }
-bash: 未预期的符号 `{top' 附近有语法错误
#错误写法
[root@shell.ceshiren.com ~]$ cpu_mem(){ top -b  -n 1 -d 1 | grep -i aliyundun$ | awk '{print $9,$10}' }
>
#正确的单行写法
cpu_mem(){ top -b  -n 1 -d 1 | grep -i aliyundun$ | awk '{print $9,$10}'; }

#多行写法
cpu_mem(){ 
  top -b  -n 1 -d 1 | grep -i aliyundun$ | awk '{print $9,$10}'; 
}

#参数化
cpu_mem(){ top -b  -n 1 -d 1 | grep -i "$1" | awk '{print $9,$10}';}

bash_profile作用

# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# User specific environment and startup programs
PATH=$PATH:$HOME/bin

export PATH

cpu_mem ()
{
    top -b -n 1 -d 1 | grep --color=auto -i "$1" | awk '{print $9,$10}'
}
  • .bash_profile 每次shell启动都会默认加载
  • PATH变量是默认找命令的地址 /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin

三剑客演练

分类统计

[root@shell.ceshiren.com ~]$ echo '
a 1
a 2
a 3
b 4
b 5
b 6
' | awk '{d[$1]+=$2}END{for(k in d) print k,d[k]}'
 0
a 6
b 15
[root@shell.ceshiren.com ~]$ echo '
a 1
a 2
a 3
b 4
b 5
b 6
' | awk '{print "d["$1"]+="$2}'
d[]+=
d[a]+=1
d[a]+=2
d[a]+=3
d[b]+=4
d[b]+=5
d[b]+=6
d[]+=
[root@shell.ceshiren.com ~]$

awk与python的对比

def test_awk():
    # awk默认词典不用初始化
    time = {}
    count = {}
    # awk把每行拆分为一个个的记录,其实就是包含每条记录的列表
    # awk通过$1 $2把每个记录又拆分成了小列表
    data = [
        ["a", 1],
        ["a", 2],
        ["a", 3],
        ["b", 4],
        ["b", 5],
        ["b", 6]
    ]

    for record in data:
        # 对应$1
        k1 = record[0]
        # 对应$2
        k2 = record[1]
        # awk默认不用做初始化
        if k1 not in time:
            time[k1] = 0

        # 等价于 d[$1] += $2
        time[k1] += k2

        if k1 not in count:
            count[k1] = 0
        count[k1] += 1

    # 对应 for(k in d) print k,d[k]  写法基本一致
    for k in time:
        print(f"k={k}, avg={time[k] / count[k]}")

 

精简版python代码

def test_awk_mini():
    time, count = {}, {}
    data = [
        ["a", 1],
        ["a", 2],
        ["a", 3],
        ["b", 4],
        ["b", 5],
        ["b", 6]
    ]
    for record in data:
        time.setdefault(record[0], 0)  # todo: 类型判断 string默认为"" int默认为0
        time[record[0]] += record[1]
        count.setdefault(record[0], 0)
        count[record[0]] += 1

    # 对应 for(k in d) print k,d[k]  写法基本一致
    for k in time:
        print(f"k={k}, avg={time[k] / count[k]}")

 

awk代码

#     echo '
# a 1
# a 2
# a 3
# b 4
# b 5
# b 6
# ' | awk '{d[$1]+=$2}END{for(k in d) print k,d[k]}'


找出状态码第9位为404和500的错误日志,
less nginx.log | awk '$9=="404" || $9 == "500"'
awk '$9=="404" || $9 == "500"' nginx.log|less
awk '$9~/404|500/' nginx.log | less
正则表达式 : awk '$9=="404" || $9 == "500" {print $9}' nginx.log
不断计数: awk '$9~/404|500/{t+=1}END{print t}' nginx.log  
awk和sed、grep等都可以跟文件名,使用正则时,awk可直接跟正则表达式,但是sed和grep要加-E


并统计错误日志的行数


less nginx.log | awk '{print $9}'| grep -E '500|404' | wc -l
less nginx.log | awk '$9=="404" || $9 == "500"' | wc -l
正则表达式 : awk '$9=="404" || $9 == "500" {print $9}' nginx.log | wc -l
不断计数: awk '$9~/404|500/{t+=1}END{print t}' nginx.log  

取出最大的响应时间 max_response_time()

max_response_time ()
{
    less nginx.log | awk '{print $(NF-1)}' | sort -nr | head -1
}

取出top3的响应时间,并打印出对应的url max_response_time_and_url()

max_response_time_and_url ()
{
    less ~/nginx.log | awk '{print $(NF-1), $7}' | sort -rn | head -3
}

取出全部请求的平均响应时间 avg_response_time()

avg_response_time ()
{
    less nginx.log | awk '{sum+=$(NF-1)}END{print sum/NR}'
}

取出所有相同url请求的平均响应时间,并且按照响应时间排序取出top 3 avg_response_time_by_url()

avg_response_time_by_url ()
{
    less nginx.log | awk '{time[$7]+=$(NF-1); count[$7]+=1;}END{for(k in time) print time[k]/count[k], k}' | sort -nr | head -3
}

统计每个url的顶层路由地址所对应的qps qps_by_route()

比如

[05/Dec/2018:00:00:01 +0000] /topics/17112 
[05/Dec/2018:00:00:02 +0000] /topics?page=63

计算/topics的平均qps 每秒多少次请求,打印平均qps最高的top5的顶级路由

/topics 100
/cable 80
less nginx.log | 
  awk '{print $4,$7}' | 
  sed 's#[?!].*##' |
  sed -E 's#([^ ]*) *(/[^/]*).*#\1:\2#'  |
  sort | 
  awk -F: '
{cur=($3*60+$4);}
NR==1{min=cur; max=cur;}
NR>1{
count[$NF]+=1; 
if(cur<min) min=cur; 
if(cur>max) max=cur;
}
END{
for(k in count) print k,count[k]/(max-min+1)}
' | 
  sort -k2 -nr | head -5

进程与网络

每隔1s统计下aliyundun的2个进程的cpu与mem,分类汇总下10s内的平均cpu与响应时间 avg_cpu_mem_py_process()

top -b -d 1 -n 10 | grep -i aliyundun | awk '{cpu[$NF]+=$(NF-3);mem[$NF]+=$(NF-2);count[$NF]+=1}END{for(k in cpu) print k, cpu[k]/count[k], mem[k]/count[k]}'

统计当前服务器上每个监听端口对应的网络状态的数量 connections_summary()

netstat  -tn | sed 1,2d | awk '{print $4, $NF}' | awk -F: '{print $NF}' | sort | uniq -c

微信朋友圈

friend() {
    while true; do
        #获取界面,提取昵称和朋友圈内容
        adb shell 'uiautomator dump && cat /sdcard/window_dump.xml' |
            sed 's#><#>|<#g' |
            awk 'BEGIN{RS="|"}{print $0}' |
            awk -F\" '
            BEGIN{OFS="\t"}
            /e3x/{name=$4}
            /b_e/{msg=$4;print name,"|",msg}
            '
        #取出大概的滑动距离
        distance=$(
            adb shell wm size |
                awk -F' |x' '
                {
                    width=$(NF-1);
                    height=$NF;
                    print width*0.5, height*0.8, width*0.5, height*0.2}'
        )
        #利用input直接划屏
        adb shell input swipe $distance
    done
}
posted @ 2021-01-02 13:29  方园FPP  阅读(117)  评论(0编辑  收藏  举报