年后在微信读书上面看到两本关于linux shell的书,分别是《linux shell脚本攻略》 和 《linux 性能优化》。涨了写奇怪的姿势,Mark在这里。
- 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
- 定义变量
在调试一些复杂的脚本的时候,在中间执行到某一句报错了。可以另开一个终端,对这一句中的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
- 输出重定向
重定向是常见的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文件中。
-
脚本调试命令 -x
脚本开启debug模式,简直太方便了。在脚本执行的时候,会打印每一行脚本对应的命令,以及这行命令对应的结果。结果一目了然。(需要注意的是 调试信息的输出是被写入到stderr中的,如果重定向了,要注意一下看日志的位置。)- 以调试模式执行脚本
$ 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
- 在脚本中开启调试
#!/bin/bash -x # todo
- 在脚本中的某一段中开启调试模式
#/bin/bash set -x # 开启debug ... set +x # 关闭debug
- 查找 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 -rn helloworld --include='*.xml' --include='*.h' .
- grep -C
显示匹配记录的上下文
grep "hello" -C3
- grep 区间
# 查询cpu 80~89之间的日志
grep "cpu : 8[0-9]%" *.log
- 文本处理 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
- 比较方便的命令
-
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% /
top重定向到文件
top -b > profile.log # 记录某个时间的cpu和内存状态
- 查看磁盘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
- shell 多进程并行
https://blog.51cto.com/yttitan/2409618
- 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