shell脚本攻略

年后在微信读书上面看到两本关于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 

# 排除某个目录
$ grep -rn "include" . --exclude="func.c*" --exclude-dir test
./main.cpp:1:#include 
  • grep --include
grep -rn helloworld --include='*.xml' --include='*.h' .
  • 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
  • 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  [email protected]  'df -h'

Filesystem            Size  Used Avail Use% Mounted on
/dev/vda              99G   11G   84G  11% /

top重定向到文件

top -b > profile.log    # 记录某个时间的cpu和内存状态 

  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组合一些常用命令,提高开发效率。
    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'
    

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

你可能感兴趣的:(shell脚本攻略)