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
}