那些天,shell脚本中曾经踩过的坑
前些天,需要实现一个需求,用脚本轮流kill服务器上的进程,观察内存变化情况,并写日志。脚本逻辑不难,但shell脚本好久不用,看过书里的语法都忘得差不多了,中间踩了不少的坑,特此记录一下,留作后续参考。
脚本使用了两个函数,第一个是去查询内存变化,并不断写日志。用了一个loop变量来记录次数,然后就是用echo和>>符号不断写进日志文件,要注意的是shell脚本中用··(键盘1旁边的那个符号,不是单引号)包含linux命令,用$符号对变量做引用。如果函数需要传参,则在函数体内,用$1表示第一个参数,$2表示第二个参数,以此类推。部分代码如下:
function MemoryQuery() { loop=6 interval=30 while true do echo "The $loop time to kill $1,and record the memory" >> $LOG_FILE echo `date`>>$LOG_FILE echo `free` >> $LOG_FILE echo "***mem info***">> $LOG_FILE cat /proc/meminfo >>$LOG_FILE loop=`expr $loop -1` if [ $loop -eq 0 ] ;then break fi sleep $interval done }
该函数的调用方法为MemoryQuery signal
第二个函数是去不断kill各种进程,进程名称为传入参数,并在第二个函数中,完成进程杀除后,去调用前一个内存查询函数。函数代码如下:
function KillProcess() { check_result=`ps -ef|grep $1 |grep -v "grep"` echo "check $1 result is :"$check_result if [[ $check_result=~"/$1" ]] then killall -9 $1 echo "matched and killed" check_result=`ps -ef|grep $1 |grep -v "grep"` echo "check $1 result is :"$check_result echo "start to query memory" MemoryQuery $1 else echo "no" $1 "exist!" fi }
这里在查询进程是否存在时,可以在用一次grep -v "grep"把grep的输出过滤掉,这个是新学到的。另外在if语句中使用正则表达式来判断输出是否符合预期,是使用“=~”符号。关于正则表达式,网上百度找到的资料如下:
由于工作需要对用户提交的数据进行验证,这是一个简单的日期正则验证实例,有需要了解的同学可参考。
shell中的if语句需要做一个正则判断,查了一下语法记录之。
1
2
3
4
5
6
|
DATEPATTERN= "^[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}$" if [[ "$STARTDATE" =~ $DATEPATTERN ]] && [[ $ENDDATE =~ $DATEPATTERN ]]; then : else echo "date format is invalid!" exit ; fi |
常用的正则表达式
1
2
|
if [[ "$file" =~ 'start' ]] 或 if [[ "$file" =~ "start" ]] |
例子:
1
2
3
4
5
6
7
8
|
#!/usr/bin/ksh file = "10start11.s" if [[ "$file" =~ "start" ]] then echo "success" else echo "failed" fi |
只有bash才支持[[
ksh在test中应该不支持正则,用awk grep sed等工具实现吧
1
2
3
4
5
6
|
flag=` echo $ file | awk '/start/' ` if [ "$flag" = "" ]; then echo "success" else echo "failed" fi |