标签:
杂谈 |
今天要写一个监控redis内存使用的脚本
[root]# #!/bin/sh #set -xv contents='/tmp/watch_redis_info.log' d=$(date +%Y%m%d) Num_limit=10737418240 /opt/app/redis/redis-cli #dos2unix $contents Num_test=$(grep 'used_memory:' $contents |awk -F':' '{print $2}') echo $Num_test echo $Num_limit # judge if > 10737418240 (10G) if [ $Num_test -gt $Num_limit ]; then fi |
运行过程中,出现如下错误:
[root]# 166634912 10737418240 : integer expression expected line 15: [: 166634912 |
问题分析:
1.
从报错结果看,说的是15行的if判断,需要的是一个整数
2.
但是从结果的显示和推测上来看,确实是整数呀。echo
$Num_test 和echo $Num_limit
都有输出,是整数呀。
3. 百思不得其解,开启调试命令:set -xv
(将脚本中的set
-xv行的#注释去掉)
运行脚本,得到如下结果:
[root]#
./watch_redis.sh contents='/tmp/watch_redis_info.log' + contents=/tmp/watch_redis_info.log d=$(date +%Y%m%d) date +%Y%m%d ++ date +%Y%m%d + d=20120808 Num_limit=10737418240 + Num_limit=10737418240 /opt/app/redis/redis-cli + /opt/app/redis/redis-cli -h 10.0.10.72 info #dos2unix $contents Num_test=`grep 'used_memory:' $contents |awk -F':' '{print $2}'` grep 'used_memory:' $contents |awk -F':' '{print $2}' ++ grep used_memory: /tmp/watch_redis_info.log ++ awk -F: '{print $2}' + Num_test=$'167105984\r' echo $Num_test + echo $'167105984\r' 167105984 echo $Num_limit + echo 10737418240 10737418240 # judge if > 10737418240 (10G) if [ $Num_test -gt $Num_limit ]; then fi + '[' $'167105984\r' -gt 10737418240 ']' : integer expression expected line 15: [: 167105984 |
+ Num_test=$'167105984\r'
#注意这一句,怎么结果是$'167105984\r'
而不是167105984的整数,问题就出在这里
怎么会多出一个$和\r来?
1.
难道是经过grep和awk操作将这些不可见字符引入的。经多次实验,排除了这个原因。
2.
那就是/tmp/watch_redis_info.log文件中本身含有这些特殊的不可见字符
使用命令cat
-A /tmp/watch_redis_info.log ,果然发现原来这个文件生成的为dos格式的
[root]# redis_version:2.4.15^M$ ..... blocked_clients:0^M$ used_memory:167473280^M$ used_memory_human:159.71M^M$ used_memory_rss:384790528^M$ used_memory_peak:167503912^M$ used_memory_peak_human:159.74M^M$ ..... |
好了,问题找到,是由于不同的行结束符导致的问题。
将 /tmp/watch_redis_info.log 进行dos2unix转码,即:将#dos2unix
$contents 行的“#”注释符去掉
最终的脚本为:
#!/bin/sh set -xv contents='/tmp/watch_redis_info.log' d=$(date +%Y%m%d) Num_limit=10737418240 /opt/app/redis/redis-cli dos2unix $contents >/dev/null 2>&1 Num_test=`grep 'used_memory:' $contents |awk -F':' '{print $2}'` # judge if > 10737418240 (10G) if [ $Num_test -gt $Num_limit ]; then fi |
运行脚本得到的结果:
[root]#
/data/crontab/watch_redis.sh contents='/tmp/watch_redis_info.log' + contents=/tmp/watch_redis_info.log d=$(date +%Y%m%d) date +%Y%m%d ++ date +%Y%m%d + d=20120808 Num_limit=10737418240 + Num_limit=10737418240 /opt/app/redis/redis-cli + /opt/app/redis/redis-cli -h 10.0.10.72 info dos2unix $contents >/dev/null 2>&1 + dos2unix /tmp/watch_redis_info.log Num_test=`grep 'used_memory:' $contents |awk -F':' '{print $2}'` grep 'used_memory:' $contents |awk -F':' '{print $2}' ++ grep used_memory: /tmp/watch_redis_info.log ++ awk -F: '{print $2}' + Num_test=167577808 # judge if > 10737418240 (10G) if [ $Num_test -gt $Num_limit ]; then fi + '[' 167577808 -gt 10737418240 ']' |
好了,问题解决,记得将set
-xv 行删除或注释。
[永福原创]转载请注明:来自http://rickie622.blog.163.com
下面还有两个问题待解释和解决:
1.
为什么redis-cli命令生成的文件要是\r\n结尾的?在linux下,应该要自动以\n结尾吧,这个需要写redis的人去改进了。
2.
怎么在shell下,去掉这些不可见的特殊字符,将字符串直接转换成数字(不包含其他任何字符,仅数字)?
附注:
换行符在Linux和Windows下的区别以及将Linux和windows下的文件的互转的Linux命令:unix2dos,
dos2unix
一、区别
换行符:
1.windows中的换行符是\r\n,
2. linux/unix下的换行符是\n。
其中:
回车符:\r=0x0d (13)
return; #回车(carriage return)
换行符:\n=0x0a (10)
newline。#换行(newline)
二、文件格式互转命令
1.unix2dos:将具有unix风格的格式文件转化为具有window下的格式文件。
2.dos2unix:将具有windows风格的格式文件转化为unix下的格式文件。
详见:http://blog.csdn.net/wzb56/article/details/6860358