瞎扯时间
人的惰性真的很难去戒掉,每天工作下班回家后,只想瘫倒在床上,玩玩手游,刷刷抖音,甚至看看无聊至极的“爽文”,对于学习、看书啥的,完全提不起兴趣,也许正是因为如此,我才显得这么平庸而无趣吧。
现在,Now,正在清明假期,两个室友都出去浪去了,我一个人在租房里,把客厅打扫了一遍,然后就是坚持了运动,算是一点小改变吧,运动也近两周了,每天都还坚持着,只是熬夜这个糟糕的习惯依然没有戒掉,这是下一阶段的目标吧,早睡早起!
还一个目标,多多学习多多写东西,去年底计划要每个月看一本书的,今年基本上没开始,惭愧,四月了,还不开始补就晚了!平时有时间也准备多写写博客,嗯,目标在前方。
正题
最近两天在办公室工作量不大,想到平时在工作中,服务器一般都是Linux操作系统,跟踪 DM 数据库报错、慢等问题,都是把日志文件打包下载到 Win 环境,借助 UE 或者 Notepad++ 来分析,但是日志文件一般都比较大,这么一个过程其实还蛮耗时间的,就想着能不能写写shell脚本来工作,当然,这才刚刚开始,只是一个练习。
第一个脚本,统计操作系统的基础信息,比如操作系统版本、cpu信息等,因为项目很多,每个项目用到的服务器也不少,经常需要统计操作系统的一些信息,这是一个小繁琐的事情,就写了个脚本,其实这个还蛮简单的,就是把平时经常用到的命令打印到一个指定的文件而已,很简单。
#!/bin/bash # system stats script # Write this shell script by Light Ink in April 2019. # 清空日志文件 echo "" > L-Ink_sys_stats.log # 标题符 title_char="=============================" echo -e "${title_char} SYSTEM STATS ${title_char}\n" >> L-Ink_sys_stats.log # 打印系统时间 sys_date=`date ‘+%Y-%m-%d %H:%M:%S‘` echo -e "System Date:${sys_date}\n" >> L-Ink_sys_stats.log # 分割符 cutter_char="------------------------------------------------------------------------" echo -e "${cutter_char}\n" >> L-Ink_sys_stats.log # 统计操作系统版本 echo "[OS version]" >> L-Ink_sys_stats.log command="`cat /etc/redhat-release`" echo -e "${command}\n" >> L-Ink_sys_stats.log echo -e "${cutter_char}\n" >> L-Ink_sys_stats.log # 统计CPU信息 echo "[CPU model]" >> L-Ink_sys_stats.log command="`cat /proc/cpuinfo | grep name | cut -f2 -d:`" echo -e "${command}" >> L-Ink_sys_stats.log echo "[Physical Cpu nums]" >> L-Ink_sys_stats.log command="`cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l`" echo -e "${command}" >> L-Ink_sys_stats.log echo "[Cpu Cores]" >> L-Ink_sys_stats.log command="`cat /proc/cpuinfo| grep "cpu cores"| uniq`" if [ ! -n "$command" ]; then command="NULL" fi echo -e "${command}" >> L-Ink_sys_stats.log echo "[Processor]" >> L-Ink_sys_stats.log command="`cat /proc/cpuinfo| grep "processor"| wc -l`" echo -e "${command}\n" >> L-Ink_sys_stats.log echo "[CPUINFO]" >> L-Ink_sys_stats.log command="`cat /proc/cpuinfo`" echo -e "${command}\n" >> L-Ink_sys_stats.log echo -e "${cutter_char}\n" >> L-Ink_sys_stats.log # 统计内存信息 echo "[Mem Info]" >> L-Ink_sys_stats.log command="`cat /proc/meminfo`" echo -e "${command}\n" >> L-Ink_sys_stats.log echo -e "${cutter_char}\n" >> L-Ink_sys_stats.log # 磁盘使用情况 echo "[Disk Using Info]" >> L-Ink_sys_stats.log command="`df -h`" echo -e "${command}\n" >> L-Ink_sys_stats.log echo -e "${cutter_char}\n" >> L-Ink_sys_stats.log # 磁盘挂载情况 :<<eof echo "[Disk Mount Info]" >> L-Ink_sys_stats.logi command="`fdisk -l`" echo -e "${command}\n" >> L-Ink_sys_stats.log echo -e "${cutter_char}\n" >> L-Ink_sys_stats.log eof echo "[Disk Mount Info]" >> L-Ink_sys_stats.log sysuser="`echo $USER`" if [ $sysuser = "root" ]; then command="`fdisk -l`" echo -e "${command}\n" >> L-Ink_sys_stats.log echo -e "${cutter_char}\n" >> L-Ink_sys_stats.log else echo -e "(State Disk Info Error)Permission denied!" |tee -a L-Ink_sys_stats.log echo -e "\n${cutter_char}\n" >> L-Ink_sys_stats.log fi # IO 统计 echo "[IO]" >> L-Ink_sys_stats.log command="`iostat -x 3 5`" echo -e "${command}\n" >> L-Ink_sys_stats.log :<<eof # 是否继续统计 DM 数据库 想了想,这一块功能不太好做,关闭此功能开发。 flag=0 for ((i=0;i<3;i++)) do read -p "Check DMDB info?[y/n]" input if [ $input = "y" -o $input = "Y" ]; then flag=1 echo "To be continue..." >> L-Ink_sys_stats.log break elif [ $input = "n" -o $input = "N" ]; then flag=1 break else echo "Input Error!" fi done if [ $flag -eq 0 ]; then echo "【Error】Input error more than 3 times!!" |tee -a L-Ink_sys_stats.log exit 1 fi eof echo -e "${title_char} - End - ${title_char}\n" >> L-Ink_sys_stats.log echo "SYSTEM STATS DONE!"
好久没有写 shell ,基本上是个新手,在上手过程中,在 if 判断语法中还吃了小亏, [] 一般不能邻着变量名,要不然就报错,还有经常获取变量的值,忘记加 $ 符,很蠢,需要多写写。
另外,在这个脚本中,有块注释方法 :<<eof 与 eof ,期间还想着弄一些骚操作,包括自定义异常抛出,但是最后还是觉得没必要,反而太繁琐,命令错误本身就有系统异常,所以就用块注释了。
第二个脚本,是一个需要一些时间不断去完善的脚本,分析 DM 库(达梦数据库) 日志的脚本,目前实现了两个小功能,筛选报错语句和超过1s的慢SQL的功能。
#!/bin/bash # analysis dmsql logs # Write this shell script by Light Ink in April 2019. # v1.0 read -p "Please input the log name:" in_logname arr=($in_logname) echo "--------------------------------" echo "The Options:" echo "1.Find Errors" echo "2.Filter SQLs More Than 100ms" echo "3.Filter SQLs More Than 1000ms" echo "4.exit" echo "--------------------------------" read -p "Choose one option please:" in_op # 将日志中的错误信息,筛选输出至文本 Find_Errs(){ for element in ${arr[@]} do command_01="`cat $element |grep "ERR("`" echo "====================== log name: "$element" =======================" >> $1 echo "${command_01}" >> $1 done } # 将日志中超过100ms的sql语句,筛选输出至文本 Filter_SQL_100ms(){ for element in ${arr[@]} do command_02="`cat $element |egrep "[1-9][0-9][0-9]\(ms\)"`" echo "====================== log name: "$element" =======================" >> $1 echo "${command_02}" >> $1 done } # 将日志中超过1000ms的sql语句,筛选输出至文本 Filter_SQL_1000ms(){ for element in ${arr[@]} do command_03="`cat $element |egrep "[1-9][0-9][0-9][0-9]\(ms\)"`" echo "====================== log name: "$element" =======================" >> $1 echo "${command_03}" >> $1 done } # 创建文件夹目录 Create_dir(){ # ls -l 以 d 开头的即文件夹,通过 sed 将多个空格替换为单个空格,再以 cut 分割,取文件名,文件名会以空格为间隔符存到变量中 command_ls="`ls -l|egrep "^d"|sed -e ‘s/[[:space:]][[:space:]]*/ /g‘ | cut -d ‘ ‘ -f 9`" dirname=($command_ls) # 判断目录是否已经存在的标志,0表示不存在 dir_exst_flag=0 # 遍历数组,如果存在目录名,即将标志置为1,反之不变 for i in ${dirname[@]} do if [ $1 == $i ]; then dir_exst_flag=1 fi done if [ $dir_exst_flag = 0 ]; then mkdir $1 else return fi } currentMon=`date "+%Y%m"` currentTime=`date "+%Y%m%d%H%M%S"` if [ $in_op = "1" ]; then dir_name="ERR_SQLS_"$currentMon Create_dir $dir_name log_name=errlog_"$currentTime".log Find_Errs $dir_name/$log_name elif [ $in_op = "2" ]; then dir_name="More_Than_100ms_SQLs_"$currentMon Create_dir $dir_name log_name=more_than_100ms_SQLs_"$currentTime".log Filter_SQL_100ms $dir_name/$log_name elif [ $in_op = "3" ]; then dir_name="More_Than_1000ms_SQLs_"$currentMon Create_dir $dir_name log_name=more_than_1000ms_SQLs_"$currentTime".log Filter_SQL_1000ms $dir_name/$log_name elif [ $in_op = "4" ]; then exit 1 else echo "Input Error!" exit 1 fi
在这个里面,用到了 shell 中的函数,函数调用不用在 fun 的()中声明变量,直接用 $1 $2 之类的指代传入的第一个、第二个参数,还是蛮方便的。
另外,作为一个新手,发现确实自己在处理文本信息或者是字符串信息的过程中,还是缺乏很多系统的命令学习,想 sed 等命令就需要再好好学学,其实以前就看过 sed 命令,但是因为长期没实践,自己也没像样的博客或者笔记记载,就跟没学习一样,这一点还需要好好加油。
重点提示一个遍历元素的方法,dirname=($command_ls) 这样将变量转成数组,当然是有分割符的,因为代码里是空格,属于默认分割符,就没有再设置,后面再详细记载。最后再用 for 来遍历数组内容。
补充
后面代码更新,会另起新的一篇博客,链接记录会在这里,先预存好位置,也提醒自己要更新。
原文:https://www.cnblogs.com/DimInk/p/10662558.html