一、shell获取敏感词接口json数据如有更新重启nginx+lua环境
因为工作需要,需要写一个shell脚本获取对应接口的数据(其它管理后台控制的敏感词库)。因为当前平台是nginx+lua脚本,重装加载敏感词需要重启nginx.实现起来也很简单,第一点,需要对获取的json数据进行分析,shell里有一个处理json的利器 (publish:August 11, 2017 -Friday),jq 下载地址:https://stedolan.github.io/jq/download/
无需安装,下载对应32/64位的文件,在linux中增加可执行权限后即可使用,当前程序中是把jq下载下来更名成了jq。
#获取json里面对应的字段:status即为json里的字段名。 cat data.json | ./jq '.status'
另外业务中的逻辑是对比新更新的关键词文件和原来的文件是否有差异,如果没有差异就不需要进行任何处理。脚本如下:
#!/bin/bash #Note:敏感词由管理后台统一管理,其它应用服务器定时调用接口取得最新的敏感词,如有更改更新关键词并重启nginx nowtime=`date +"%Y-%m-%d %H:%M:%S"` cd /root/ oriwordtxt='/root/www/project/badword.txt' curl -o data.json http://www.badwords.com/wordList.php?getall #返回的json有两个字段:一个status表示响应状态,一个words是敏感词列表 status=`cat data.json | ./jq '.status'` if [ "s$status" = "s1" ] ; then words=`cat data.json | ./jq '.words'` wordchar='' for word in $words do if [ "$word" != "[" -a "$word" != "]" ]; then wordt=`echo $word | tr -d '",'` wordchar=${wordchar}${wordt}'\n' fi done echo -e $wordchar > data.txt sed -i 's/"\(.*\)",*/\1/g' data.txt sed -i '/^$/d' data.txt diff data.txt $oriwordtxt if [[ $? = 0 ]];then echo "$nowtime no change" else cp -f data.txt $oriwordtxt /opt/modules/nginx/sbin/nginx -s reload echo "$nowtime reload nginx" fi else echo '$nowtime error:{$status}' fi
最后增加定时执行任务,即可。
二、一个逐步删除服务器上文件夹的shell脚本
因为图片在第一次请求后就缓存在服务器上,接下来再请求就直接请求文件,不需要再执行PHP。因为需要批量全部更新服务器的图片文件,经统计总共有1000个图片文件夹,共计图片约130万张(每台服务器上均有),所以担心一次性删除所有图片会瞬间造成服务器压力过大,因此有必要采用逐步清理图片文件夹。
脚本如下,每12分钟执行一次清理,一次清理10个图片文件夹,约删除13000张图片,经观察,在执行一次之后服务器的的负载会增加1.0左右。之后因为图片生成负载会逐步下降至正常至下次再删除时循环变化。这样形成良性循环服务器不会有任务问题。
注图片目录存放在/image/web/news/目录下,均以img开头后是根据内容ID对1000取模后的数字存放。采用nohup挂在后台运行,删除至999后自动停止。并记录删除的目录文件夹日志及操作时间。
#!/bin/sh #执行删除图片目录文件夹,1次删除10个文件,每次中间间隔1小时。 #执行脚本:cd /opt/doimage/ && sudo nohup /opt/doimage/clear_img.sh >> /opt/doimage/img.log 2>&1 & while true; do start=`cat start.log` end=$(expr $start + 10) for((s=$start;s<$end;s++)); do if(( $s >999 )); then exit; fi imgdir='/image/web/news/img'$s #imgdir='/opt/doimage/'$s sudo rm -rf $imgdir echo 'delete:'$imgdir; done if(( $end >999 )); then break; fi echo `date +%Y-%m-%d' '%H:%M:%S` echo $end>start.log sleep 720 done
生成日志如下:
delete:/image/web/news/img0
delete:/image/web/news/img1
delete:/image/web/news/img2
delete:/image/web/news/img3
delete:/image/web/news/img4
delete:/image/web/news/img5
delete:/image/web/news/img6
delete:/image/web/news/img7
delete:/image/web/news/img8
delete:/image/web/news/img9
2017-10-13 17:43:56
delete:/image/web/news/img10
delete:/image/web/news/img11
delete:/image/web/news/img12
delete:/image/web/news/img13
delete:/image/web/news/img14
delete:/image/web/news/img15
delete:/image/web/news/img16
delete:/image/web/news/img17
delete:/image/web/news/img18
delete:/image/web/news/img19
2017-10-13 17:56:03
...
...
delete:/image/web/news/img998
delete:/image/web/news/img999
三、Php中英文及外文字符串的切割编码问题
程序中总不了字符串切割,而程序员们也习惯了拿来主义,百度一搜就得到了想要的函数,然后屡试不爽。比如下面一个学用的混合字符串切割方法(publish:October 15, 2017 -Sunday):
#utf8编码字符串切割的原理 public function utf8StrSplit($str) { $split = 1; $array = array(); for($i = 0; $i < strlen($str); ) { $value = ord($str[$i]); if ($value < 128) { $split = 1; } else { if ($value >= 192 && $value <= 223) { $split = 2; } elseif ($value >= 224 && $value <= 239) { $split = 3; } elseif ($value >= 240 && $value <= 247) { $split = 4; } } $key = NULL; for ($j = 0; $j < $split; $j++, $i++) { $key .= $str[$i]; } array_push($array,$key); } return $array; }
拿来用,充分利用外部资源当然是好事,也是能力的一部分,但是如果有时间有精力并且有一定必要,也可以去弄清楚它本身的逻辑。今天找个时间又看了点编码的问题,说实话两年前也就这个看了很多资料,但是脑子总是不够用,到今天好像忘得差不多了。上述方法中为什么是ascii码值为192-247的字符需要做特殊处理呢?
因为UTF-8是一个多字节(multi-byte)可变宽度(variable-width)编码,它的编码规则中依然把0至127留给了ASCII,而把192至247作为换挡键(key),128至192作为被换挡的对象。举个例子,使用字符208和209能切换进入西里尔文字符范围,字符175后跟换挡键208对应符1071,也就是西里尔文中的Я,具体的计算方法是 (208%32)*64 + (175%64) = 1071。字符224至239是双倍换挡键。字符190跟换挡键226,在加上字符128对应字符12160:⾀ 字符240和之后的换挡键是三倍换挡键。记谓的换档就是表明这后面的这个字符是占了几个字节,因此如果要正常地显示这个字符,需要连续读出后面要求的字节长度,才能正确显示字符。
如此上面的字符串切割方法就一目了然,只要知道每次截取的时候应该截几字字符,字符就不会出错。
有篇相关文章,作者也是费心了。值得一看,存个链接在这里:关于Unicode和URL encoding入门的一切以及注意事项 - hh54188 - 博客园