Linux常用命令

命令分类

  • 文件:everything is file
  • 进程:文件的运行形态
  • 网络:特殊文件

文件

  • 磁盘与目录:dflscdpwd$PWD
  • 文件编辑:交互编辑vim、流式编辑器sed
  • 文件权限:chmodchown
  • 文件搜索:find
  • 文件内容:catmorelessgrep
  • 特殊文件:软链、socket:进程通讯、管道:进程通讯

文件权限

  • ls -l查看权限
  • 文件、目录
  • 用户、组
  • 读、写、执行、SUID、SGID
  • chmod:修改归属者
  • chgrp:修改归属组

进程

  • top
  • ps

网络

  • netstat -tlnp
  • netstat -tnp
  • Mac与Linux不一致:netstat -p tcp -n -a

Shell Piping管道

Shell输入输出

  • read用来读取输入,并赋值给变量
  • echoprintf可以简单输出变量
  • >file将输出重定向到另一个文件
  • >>表示追加等价于tee -a
  • <file输入重定向
  • |表示管道,也就是前一个命令的输出传入下一个命令的输入

文件描述

  • 输入文件——标准输入0
  • 输出文件——标准输出1
  • 错误输出文件——标准错误2

image-20210308204841170

管道

  • 把不同程序的输入和输出连接
  • 可以连接更多命令
  • 常见的组合命令Linux三剑客

image-20210308205102836

Nginx日志分析

日志的格式:

1
2
3
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 .
139.180.132.174 - - [05/Dec/2018:00:09:20 +0000] "GET /bbs.zip HTTP/1.1" 404 1264 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36" 0.011 0.011 .
139.180.132.174 - - [05/Dec/2018:00:09:12 +0000] "GET /__zep__/js.zip HTTP/1.1" 500 2183 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36" 0.018 0.018 .

日志数据检索

  1. 找出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 500
    • sort:排序
    • 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
  1. 找出500错误时候的上下文,找出500错误的前两行,考察grep高级用法

    1
    [root@lvjing ~]# grep -B 2 "HTTP\/1.1\" 500" nginx.log

日志数据统计

  1. 找出访问量最高的ip 统计分析

    1
    [root@lvjing ~]# cat nginx.log | awk '{print $1}' | sort | uniq -c | sort -nr | head -10
  2. 找出相同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
    21
    function 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 定义函数
function url_summary {
#管道符后面可以换行
cat $1 |
awk '{print $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 | uniq -c | sort -nr | 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
584 /cable
372 /topics/int
147 /topics/int/replies/int/edit
94 /
49 /topics/int/replies/int/reply_suggest
41 /topics/int/show_wechat
26 /uploads/photo/2017/id.png!large
25 /topics/int/replies/int/reply_to
25 /_img/uploads/photo/2017/id.png!large
21 /uploads/user/avatar/id.jpg!md
20 /_img/uploads/user/avatar/id.jpg!md
18 /uploads/photo/2018/id.png!large
15 /_img/uploads/photo/2018/id.png!large
13 /uploads/photo/2018/id.gif!large
13 /_img/uploads/photo/2018/id.gif!large
7 /uploads/user/avatar/int/id.jpg!large
7 /id.png
7 /api/v3/topics.json
7 /account/sign_in
6 /uploads/user/avatar/int/id.jpg!sm

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
    26
    perf_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