Shell实战
Linux常用命令
命令分类
- 文件:everything is file
- 进程:文件的运行形态
- 网络:特殊文件
文件
- 磁盘与目录:
df
、ls
、cd
、pwd
、$PWD
- 文件编辑:交互编辑vim、流式编辑器sed
- 文件权限:
chmod
、chown
- 文件搜索:
find
- 文件内容:
cat
、more
、less
、grep
- 特殊文件:软链、socket:进程通讯、管道:进程通讯
文件权限
ls -l
查看权限- 文件、目录
- 用户、组
- 读、写、执行、SUID、SGID
chmod
:修改归属者chgrp
:修改归属组
进程
top
ps
网络
netstat -tlnp
netstat -tnp
- Mac与Linux不一致:
netstat -p tcp -n -a
Shell Piping管道
Shell输入输出
read
用来读取输入,并赋值给变量echo
、printf
可以简单输出变量>file
将输出重定向到另一个文件>>
表示追加等价于tee -a
<file
输入重定向|
表示管道,也就是前一个命令的输出传入下一个命令的输入
文件描述
- 输入文件——标准输入0
- 输出文件——标准输出1
- 错误输出文件——标准错误2
管道
- 把不同程序的输入和输出连接
- 可以连接更多命令
- 常见的组合命令Linux三剑客
Nginx日志分析
日志的格式:
1 | 123.127.112.18 - - [05/Dec/2018:00:09:18 +0000] "GET /cable HTTP/1.1" 101 1017 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36" 70.577 70.577 . |
日志数据检索
找出log中的404 500的报错,输出整行内容,考察严谨性
1
2
3[root@lvjing ~]# less nginx.log | awk '$9~/500|404/{print $0}'
[root@lvjing ~]# less nginx.log | awk '$9~/500|404/{print $0}' | wc -l
267统计nginx.log中status_code的数量
1
2
3
4
5
6
7
8
9
10
11[root@lvjing ~]# less nginx.log | awk '{print $9}' | sort | uniq -c
433 101
828 200
304 301
152 302
5 304
7 401
266 404
2 422
2 499
1 500sort
:排序uniq -c
:去重
awk统计nginx.log中status_code=404和status_code=500的数量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16[root@lvjing ~]# cat nginx_demo_1.awk
BEGIN {
printf "%-10s%-50s\n","Status_code","Amount"
}
{
if($9==404 || $9==500)
CODE[$9]++
}
END {
for(u in CODE)
printf "%-10s%-50d\n",u,CODE[u]
}
[root@lvjing ~]# awk -f nginx_demo_1.awk nginx.log
Status_codeAmount
404 266
500 1
找出500错误时候的上下文,找出500错误的前两行,考察grep高级用法
1
[root@lvjing ~]# grep -B 2 "HTTP\/1.1\" 500" nginx.log
日志数据统计
找出访问量最高的ip 统计分析
1
[root@lvjing ~]# cat nginx.log | awk '{print $1}' | sort | uniq -c | sort -nr | head -10
找出相同url的平均响应时间
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18[root@lvjing ~]# cat nginx_url_avg.awk
BEGIN {
printf "%-50s%30s\n", "url","avg_time"
}
{
url_count[$7]++
response_time_sum[$7]+=$(NF-1)
}
END {
for(url in url_count)
printf "%-50s%30d\n",url,response_time_sum[url]/url_count[url]
}
[root@lvjing ~]# awk -f nginx_url_avg.awk nginx.log
……
/topics/node55 0
/topics/12322/replies/101177/edit 0
/favicon-16x16.png 0
……结合sed修改访问url(具体规则,查看“数据文件修改”),进行统计
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21function url_summary {
#管道符后面可以换行
cat $1 |
awk '{print $(NF-1),$7}' |
#sed的多个表达式合并
sed -e 's/\?.*//g' \
-e 's/\/avatar\/[0-9]*/\/avatar\/int/g' \
-e 's/\/topics\/[0-9]*/\/topics\/int/g' \
-e 's/\/replies\/[0-9]*/\/replies\/int/g' |
sed -e 's/\/[0-9a-z\-]*\.png/\/id.png/g' |
sed -e 's/\/[0-9a-z\-]*\.jpg/\/id.jpg/g' |
sed -e 's/\/[0-9a-z\-]*\.jpeg/\/id.jpeg/g' |
sed -e 's/\/[0-9a-z\-]*\.gif/\/id.gif/g' |
sort -k 2 |
awk '{total[$2]+=$1; times[$2]++;} END{for(url in total){avg=sprintf("%.3f", total[url]/times[url]); print(avg, url)}}' |
sort -k 1 -nr |
awk 'BEGIN{printf("%-s\t%s\n", "平均响应时间", "接口地址")} {printf("%-8s\t%s\n", $1, $2)}' |
head -20
}
url_summary $1执行结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21[root@lvjing ~]# sh nginx_url.sh nginx.log
平均响应时间 接口地址
3707.261 /cable
1.489 /account/auth/github/callback
0.334 /uploads/user/avatar/id.jpg!large
0.312 /xuebi
0.309 /Alin_01/favorites
0.308 /Lihuazhang/replies
0.283 /uploads/photo/2018/id.png!large
0.242 /tingyunapm
0.221 /topics/intno_reply
0.179 /benlooking/replies
0.168 /lose/replies
0.164 /eurekasaber/replies
0.162 /kuki_sini/replies
0.161 /topics/intlast
0.160 /topics/int
0.157 /anonymous/replies
0.153 /topics/intnode81
0.148 /topics/intlast_reply
0.146 /cay/replies
数据文件修改
找出访问量最高的页面地址 借助于sed的统计分析
/topics/16689/replies/124751/edit
把数字替换为/topics/int/replies/int/edit
/_img/uploads/photo/2018/c54755ee-6bfd-489a-8a39-81a1d7551cbd.png!large
变成/_img/uploads/photo/2018/id.png!large
/topics/9497 改成 /topics/int
- 其他规则参考如上
输出
- url pattern对应的请求数量
- 取出top 20请求量的url pattern
1 | # 定义函数 |
脚本执行
1 | [root@lvjing ~]# sh nginx_url.sh nginx.log |
Linux性能统计分析
网络统计
访问当前机器22端口的tcp连接数
1
netstat -tn 2>/dev/null | grep "^tcp" | grep -v '127.0.0.1' |awk '$4~/:22$/ {print $5}' | wc -l
访问当前机器22端口的IP数
1
netstat -tn 2>/dev/null | grep "^tcp" | grep -v '127.0.0.1' | awk '$4~/:22$/ {print $5}' | awk -F: '{print $1}' |sort | uniq -c | wc -l
性能统计
统计某个进程的cpu和mem的增长情况
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26perf_get() {
# 使用变量替换位置参数
# 监控的程序
local proc="$1"
# 监控的次数
local timeout="$2"
# 基本使用给予基本检查
[ -z "$proc" ] && { echo please give a proc name or pid; return 1; }
[ -z "$timeout" ] && timeout=10
# top的批处理输出
top -b -d 1 -n $timeout |
# 范围限定,为了精准处理
grep '^[ 0-9][1-9]' |
# 提取精准数据
awk '{print $1,$9,$10,$12}' |
# 取出感兴趣数据,同时读一行就给后面的管道进程,方便实时显示
grep --line-buffered -i "$proc" |
# 分组统计并打印,使用tab作为OFS进行输出,fflush()可以实时输出给后面的进程
awk 'BEGIN{OFS="\t";print "CPU","MEM"}
{cpu+=$2; mem+=$3;print $1,$2,$3,$4;}
END{print "";print "avg: ",cpu/NR,mem/NR}'
}
perf_get $1 $2执行结果
1
2
3
4
5
6
7[root@lvjing ~]# sh perf_system.sh java 3
CPU MEM
141860 0.0 16.8 java
141860 0.0 16.8 java
141860 0.0 16.8 java
avg: 0 16.8
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Jing's Blog!