美文网首页
shell脚本攻略

shell脚本攻略

作者: DayDayUpppppp | 来源:发表于2022-03-07 21:17 被阅读0次

    年后在微信读书上面看到两本关于linux shell的书,分别是《linux shell脚本攻略》 和 《linux 性能优化》。涨了写奇怪的姿势,Mark在这里。


    1. tee 命令
      比如某条命令 既希望它可以输出到终端上,有希望可以输出到某个文件上记录结果。那么tee命令就非常方便了。
    pidstat -p 2159985  1 10 | tee result.log
    09:10:11 PM   UID       PID    %usr %system  %guest   %wait    %CPU   CPU  Command
    09:10:12 PM  1000   2159985    0.00    0.00    0.00    0.00    0.00     1  cpptools-srv
    09:10:13 PM  1000   2159985    0.00    0.00    0.00    0.00    0.00     1  cpptools-srv
    09:10:14 PM  1000   2159985    0.00    0.00    0.00    0.00    0.00     1  cpptools-srv
    09:10:15 PM  1000   2159985    0.00    0.00    0.00    0.00    0.00     1  cpptools-srv
    09:10:16 PM  1000   2159985    0.00    0.00    0.00    0.00    0.00     1  cpptools-srv
    09:10:17 PM  1000   2159985    0.00    0.00    0.00    0.00    0.00     1  cpptools-srv
    09:10:18 PM  1000   2159985    0.00    0.00    0.00    0.00    0.00     1  cpptools-srv
    

    1. 定义变量

    在调试一些复杂的脚本的时候,在中间执行到某一句报错了。可以另开一个终端,对这一句中的shell变量快速定义一下,单独执行这一句,迅速定位到问题。比如:

    • 在终端上定义变量
    SVN="svn"
    OPTION="--version"
    
    ${SVN} ${OPTION} 
    svn, version 1.6
    compiled Nov 17 2021, 18:34:55 on x86_64-unknown-linux-gnu
    
    • export导入环境变量
    echo $PATH
    /usr/lib64/ccache:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin
    
    # 临时导入一个新的path
    export PATH=$PATH:~/dev_test
    

    1. 输出重定向

    重定向是常见的shell操作了

    • 对于脚本的执行,可以把输出重定向到文件。
    # 分别将标准输出重定向到某文件,将标准错误重定向到某文件
    ./exec.sh 1>std.out 2>std.err
    
    # 把标准输出和标准错误都重定向到某文件
    ./exec.sh &>out.log
    
    # 把标准错误也重定向到标准输出
    ./exec.sh 1>std.out 2>&1  
    

    很多shell的教程或书里面,并没有介绍&的作用。其实,
    在这里2>&1&的作用类似于转移符号,如果写为2>1那就是标准错误写入到名称是1文件中。


    1. 脚本调试命令 -x
      脚本开启debug模式,简直太方便了。在脚本执行的时候,会打印每一行脚本对应的命令,以及这行命令对应的结果。结果一目了然。(需要注意的是 调试信息的输出是被写入到stderr中的,如果重定向了,要注意一下看日志的位置。)

      1. 以调试模式执行脚本
      $ cat test.sh 
      #/bin/bash
      echo `date`
      
      $ bash -x test.sh 
      ++ date
      + echo Sun Mar 6 16:07:33 CST 2022
      Sun Mar 6 16:07:33 CST 2022
      
      1. 在脚本中开启调试
      #!/bin/bash -x 
      # todo
      
      1. 在脚本中的某一段中开启调试模式
      #/bin/bash 
      
      set -x   # 开启debug
      ...
      
      set +x  # 关闭debug
      

    1. 查找 find,grep ,sort ,xargs ,alias
    • 查看某个目录下,包含Item的文件
    find . -name  "*Item*"         
    find . -iname "*Item*"    -iname 表示忽略大小写
    
    • 查找某个目录下,包含malloc关键字的.c文件
    find . -name "*.c" | xargs grep "malloc" --color
    
    • grep 递归查找 + color
    grep -rn "ERROR" --color
    
    • grep 忽略大小写
    grep -rn -i "error"  *.log
    
    • grep -v 排除某个类的关键字
    grep "ERROR" *.log  | grep -v "Init"   # 查到error 并且排除init关键字
    
    • grep --exclude=
    $ ll
    total 8.0K
    -rw-r--r-- 1  140 Mar  6 16:38 func.cpp
    -rw-r--r-- 1  147 Nov 10 15:10 main.cpp
    
    # 排除某个文件
    $ grep "include" *.cpp --exclude="func.c*"
    main.cpp:#include <iostream>
    
    # 排除某个目录
    $ grep -rn "include" . --exclude="func.c*" --exclude-dir test
    ./main.cpp:1:#include <iostream>
    
    • grep --include
    grep -r "include" . --include *.cpp 
    grep -r "include" . --include *.{cpp,c}
    
    • grep -C

    显示匹配记录的上下文

    grep "hello" -C3
    
    • grep 区间
    # 查询cpu 80~89之间的日志
    grep "cpu : 8[0-9]%" *.log
    

    1. 文本处理 awk 和 sort
    • awk

    awk基本格式:

    awk 'BEGIN{STATEMENT}  {STATEMENT}  END{STATEMENT}'  filename
    

    awk的几个特殊变量:

    $0  表示这行全部内容
    $1  表示被分隔符分割的第一个内容
    $2  表示被分隔符分割的第二个内容
    
    • 查找日志中cpu利用率超过90%的时间段
    awk -F'%' '{print $1}'| awk '{if ($NF > 90) print $0}'
    
    • 统计日志中出现FATAL的次数
    grep FALAL log* | awk '{print $13}' | awk '{sum[$1]+=1} END{for (k in sum) print k ": " sum[k]}'
    
    • 统计日志中word出现的次数
    cat /etc/fstab | awk '{for(i=1;i<NF;i++){count[$i]++}}END{for(i in count) {print i,count[i]}}'
    
    • awk使用substr打印前n个字符
    cat /etc/passwd | awk -F : '{print substr($1,0,3)}'
    
    • 统计msg id出现的次数
    cat file 
    msg id : 100
    msg id : 200
    msg id : 300
    msg id : 200
    msg id : 300
    msg id : 300
    
    方法1:
    cat file | awk '{print $4}' | sort | uniq -c
          1 100
          2 200
          3 300
    
    方法2:
    cat file | awk '{a[$4]++} END{for( i in a) print i" "a[i]}'
    100 1
    200 2
    300 3
    

    • sort 命令
      常用的几个参数:
      -n 表示按照数值排序
      -r 表示逆序排序
      -k 表示第x列
    $ cat test_sort.txt 
    1 twitter  300
    2 apple    20
    3 google   40
    4 faceback 1000
    
    # 根据第一列按照数值的大小 逆序排序
    $ sort -nrk 1 test_sort.txt 
    4 faceback 1000
    3 google   40
    2 apple    20
    1 twitter  300
    
    # 根据第三列按照数值的大小 逆序排序
    $ sort -nrk 3 test_sort.txt 
    4 faceback 1000
    1 twitter  300
    3 google   40
    2 apple    20
    

    1. 比较方便的命令
    • ssh-copy-id命令
      自动将私钥拷贝到远程服务器上

      ssh-copy-id USER@IP
      
    • mktemp 命令
      可以为临时文件或目录创建唯一的名字

    • sshpass 命令
      在某台机器上面远程执行一条命令:

    sshpass -p ${passwd}  ssh -p xxx -o StrictHostKeyChecking=no  dev@10.xxx.xx.1  'df -h'
    
    Filesystem            Size  Used Avail Use% Mounted on
    /dev/vda              99G   11G   84G  11% /
    

    1. 查看磁盘io,查看网络io
    • 如何定位到磁盘io高的进程

    比如有个进程在io,怎么找到它?

    [ ~]$ pidstat 1
    Linux  (VM)     03/07/2022  _x86_64_    (16 CPU)
    09:20:16 PM       PID    %usr %system  %guest    %CPU   CPU  Command
    09:20:17 PM       412    0.99    3.96    0.00    4.95     1  svn
    

    或者iotop

    Total DISK READ: 10.69 M/s | Total DISK WRITE: 2.20 M/s
    TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND                                                                                                                      
    412  be/4    xxxx   10.61 M/s   10.77 M/s  0.00 % 89.59 % svn up .
    

    • 如果定位到网络io高的进程

    iftop 命令

    iftop -P
    找到某个tcp连接的流量异常 
    
    netstat -tunp | grep 端口
    
    • 内存
    # 查看内存
    free -g
    
    # 按照内存排序
    top 后输入M
    

    查看oom

    cat /var/log/message | grep Kill
    
    • cpu
      cpu占用率查看:
    top
    

    查看某一个进程:

    pidstat 1 10 -p xxx
    

    查看线程

    top -H -p pid
    

    1. shell 多进程并行
      https://blog.51cto.com/yttitan/2409618

    1. alias
      利用alias组合一些常用命令,提高开发效率。

    grep 大集合:

    # grep alias 
    alias ga='grep_all() { grep -n --color -ir $* ./; }; grep_all'
    
    // 查找xml
    alias gxml='grep_xml() { find . -iname "*.xml*" | xargs grep -n -ir $* --color}; grep_xml'
    
    // 查找c文件
    alias gc='grep_c() {find . -name "*.c" | xargs grep -n -ir $* --color}; grep_c'
    
    // 查找cpp文件和hpp文件
    alias gcpp='grep_cpp() {find . -name "*.cpp" | xargs grep -n -ir $* --color}; grep_cpp'
    alias ghpp='grep_hpp() {find . -name "*.h" | xargs grep -n -ir $* --color}; grep_hpp'
    alias gpp='grep_pp() {find . -name "*.[hc]p*" | xargs grep -n -ir $* --color}; grep_xml'
    
    // 到某个log目录下面 查某个关键字
    alias gtask='gtask() {find ~/workspace/task/log -iname "*.log" | xargs -t grep -n -ir $* --color}; gtask'
    

    参考:
    网络io: https://blog.csdn.net/monkeynote/article/details/45867803
    磁盘io: https://www.cnblogs.com/zhanglianghhh/p/12262009.html

    相关文章

      网友评论

          本文标题:shell脚本攻略

          本文链接:https://www.haomeiwen.com/subject/syfwrrtx.html