一、for循环
for循环结构 语法
for 变量名 in 变量取值列表
do
指令。。。
done
#另一种
for((exp1;exp2;exp2))
do
指令。。。
done
https://blog.51cto.com/oldboy/711342 《linux下批量修改文件名精彩解答案例分享》
例子13 生产环境批量检查web服务是否正常并且发送相关邮件或手机报警
#!/bin/bash
#set -x
RETVAL=0
SCRIPTS_PATH="/server/scripts"
MAIL_GROUP="3xxxxxx1@qq.com 4xxxxxxx8@qq.com"
## web detection function
LOG_FILE="/tmp/web_check.log"
function Get_Url_Status(){
FAILCOUNT=0
for (( i=1 ; $i <= 3 ; i++ ))
do
#跟之前的检测网站一样,检测网页响应
wget -T 20 --tries=2 --spider http://${HOST_NAME} >/dev/null 2>&1
if [ $? -ne 0 ]
then
let FAILCOUNT+=1;
fi
done
#if 3 times then send mail. 发邮件
if [ $FAILCOUNT -eq 3 ]
then
RETVAL=1
NOW_TIME=`date +"%m-%d %H:%M:%S"`
SUBJECT_CONTENT="http://${HOST_NAME} service is error,${NOW_TIME}."
for MAIL_USER in $MAIL_GROUP
do
echo "send to :$MAIL_USER ,Title:$SUBJECT_CONTENT" >$LOG_FILE
mail -s "$SUBJECT_CONTENT " $MAIL_USER <$LOG_FILE
done
else
RETVAL=0
fi
return $RETVAL
}
#func end.
[ ! -d "$SCRIPTS_PATH" ] && {
mkdir -p $SCRIPTS_PATH
EOF
}
#定义要检测的网站
[ ! -f "$SCRIPTS_PATH/domain.list" ] && {
cat >$SCRIPTS_PATH/domain.list<<EOF
www.etiantian.org
blog.etiantian.org
EOF
}
#service check
for HOST_NAME in `cat $SCRIPTS_PATH/domain.list`
do
echo -n "checking $HOST_NAME: "
#Get_Url_Status
Get_Url_Status && echo ok||echo no
done
例子 批量创建用户 并附上随机密码
userchars="test"
passfile="/tmp/user.log"
for num in `seq 3`
do
useradd $userchars$num
passwd="`echo "date $RANDOM"|md5sum|cut -c3-11`"
echo "$passwd"|passwd --stdin $userchars$num
echo -e "user:$userchars$num\tpasswd:$passwd">>$passfile
#sleep 1
done
echo ------this is oldboy trainning class contents----------------
cat $passfile
接上回的shell内容。
范例7。分析图片服务日志。把日志(每个图片访问次数*图片大小的总和〉排行,取top10,也就是计算每个url的总访问大小
说明。这个功能可以用于网站流窒带宽很高,分析自己的服务器哪些元素占用流量大,进而进行优化栽剪图片,压缩js等措施。 日志信息如下:
59.33.26.105 - - [08/Dec/2010:15:43:55 +0800] "GET //back/upload/course/2010-10-25-23-48-59-048-18.jpg HTTP/1.1" 200 44286 "http://oldboy.blog.51cto.com/static/web/column/17/index.shtml?courseId=43" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)"
59.33.26.105 - - [08/Dec/2010:15:43:55 +0800] "GET /back/upload/teacher/2010-08-06-11-39-59-0469.jpg HTTP/1.1" 200 10850 "http://oldboy.blog.51cto.com/static/web/column/17/index.shtml?courseId=43" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)"
59.33.26.105 - - [08/Dec/2010:15:43:55 +0800] "GET /back/upload/teacher/2010-08-30-13-57-43-06210.jpg HTTP/1.1" 200 11809 "http://oldboy.blog.51cto.com/static/web/column/17/index.shtml?courseId=43" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)"
59.33.26.105 - - [08/Dec/2010:15:43:55 +0800] "GET /static/web/coursesort/5.shtml HTTP/1.1" 200 255 "http://oldboy.blog.51cto.com/static/web/column/17/index.shtml?courseId=43" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)"
59.33.26.105 - - [08/Dec/2010:15:43:55 +0800] "POST /cms/cmtweb!getCommentListBySource.action HTTP/1.1" 200 433 "http://oldboy.blog.51cto.com/static/web/column/17/index.shtml?courseId=43" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)"
59.33.26.105 - - [08/Dec/2010:15:43:56 +0800] "GET /static/images/photos/2.jpg HTTP/1.1" 200 11299 "http://oldboy.blog.51cto.com/static/web/column/17/index.shtml?courseId=43" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)"
59.33.26.105 - - [08/Dec/2010:15:43:56 +0800] "GET /static/images/photos/2.jpg HTTP/1.1" 200 11299 "http://oldboy.blog.51cto.com/static/web/column/17/index.shtml?courseId=43" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)"
59.33.26.105 - - [08/Dec/2010:15:43:56 +0800] "GET /static/images/photos/2.jpg HTTP/1.1" 200 11299 "http://oldboy.blog.51cto.com/static/web/column/17/index.shtml?courseId=43" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)"
59.33.26.105 - - [08/Dec/2010:15:44:02 +0800] "GET /static/flex/vedioLoading.swf HTTP/1.1" 200 3583 "http://oldboy.blog.51cto.com/static/flex/AdobeVideoPlayer.swf?width=590&height=328&url=/[[DYNAMIC]]/2" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)"
124.115.4.18 - - [08/Dec/2010:15:44:15 +0800] "GET /?= HTTP/1.1" 200 46232 "-" "-"
124.115.4.18 - - [08/Dec/2010:15:44:25 +0800] "GET /static/js/web_js.js HTTP/1.1" 200 4460 "-" "-"
124.115.4.18 - - [08/Dec/2010:15:44:25 +0800] "GET /static/js/jquery.lazyload.js HTTP/1.1" 200 1627 "-" "-"
124.115.4.18 - - [08/Dec/2010:15:44:25 +0800] "GET /static/js/common.js HTTP/1.1" 200 1861 "-" "-"
124.115.4.18 - - [08/Dec/2010:15:44:25 +0800] "GET /static/js/default.js HTTP/1.1" 200 2686 "-" "-"
124.115.4.18 - - [08/Dec/2010:15:44:25 +0800] "GET /static/js/cookieUtil.js HTTP/1.1" 200 955 "-" "-"
124.115.4.18 - - [08/Dec/2010:15:44:25 +0800] "GET /static/js/jquery-jquery-1.3.2.min.js HTTP/1.1" 200 57254 "-" "-"
124.115.4.18 - - [08/Dec/2010:15:44:26 +0800] "GET /static/js/addToCart.js HTTP/1.1" 200 6417 "-" "-"
123.122.65.226 - - [08/Dec/2010:15:44:43 +0800] "GET /static/flex/vedioLoading.swf HTTP/1.1" 304 - "http://oldboy.blog.51cto.com/static/flex/VideoCenter.swf?url=/[[DYNAMIC]]/2" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"
123.122.65.226 - - [08/Dec/2010:15:44:43 +0800] "POST /messagebroker/amf HTTP/1.1" 200 183 "http://oldboy.blog.51cto.com/static/flex/VideoCenter.swf?url=/[[DYNAMIC]]/4" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"
123.122.65.226 - - [08/Dec/2010:15:44:43 +0800] "POST /messagebroker/amf HTTP/1.1" 200 117 "http://oldboy.blog.51cto.com/static/flex/VideoCenter.swf?url=/[[DYNAMIC]]/4" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"
需要的数据是(图中标红的)
最终结果是某个文件的访问次数和消耗的流量,所以考虑建立以文件名为索引的两个数组,一个存储访问次数,一个保存消耗的流量,这样当使用awk按行遍历文件时,对次数数组+1,同时对流量数组进行文件大小的累加,等文件扫描完成。再遍历输出两个数组既可以得到该文件的反间次数和总的流量消耗。
#{array_num[$7]++ 数组第七列的,只要出现一次相同的文件名那就++ , 这个就相当于访问次数了
#arrzy_size[$7]+=$10 ,把第七列相同的,将后面的$10进行加和。 相当于总访问量
awk '{array_num[$7]++;array_size[$7]+=$10}END{for(x in array_num){print array_size[x],array_num[x],x}}' log.txt | sort -nr -k1 | head -n 10
二、shell函数
函数名(){
指令...
return n
}
function 函数名(){
指令...
return n
}
#加载函数
. ./func-1.sh
#提示:可以用source或.(点号)来加载脚本function.sh中的命令或变量参数等。
略。。。
三、shell脚本调试
使用dos2unix命令处理脚本
从windows编辑的脚本到linux下的格式可能会出现格式问题,可用cat -A filename.txt来查看情况。
可用dos2unix来格式化处理,处理完之后可发现 ^M 消失了
使用bash命令参数调试
sh [-nvx] scripts.sh
-n:不会执行该脚本,仅查询脚本语法是否有问题,并给出错误提示。
-v:在执行脚本时,先将脚本的内容输出到屏幕上,如果有错误,也会给出错误提示。
-x:将使用的脚本内容显示到屏幕上,这是对调试很有用的参数。
或者直接在脚本中使用 set -x
四、shell编程规范
变量命名规范
统一、全部大写或者驼峰命名
引用时: ${APACHE_ERR_NUM} 或"${APACHE_ERR_NUM}"
函数命名
函数命名使用单词首字母大写,如CreateFile 。 或驼峰命名 createFile
建议函数定义时在函数名前加上 function保留字,如:
function testA(){
echo "test aaaaa"
}
testA()
引用符号使用规范
配置规范
补充
19 对于java程序脚本等需要环境变量的,在写脚本前,最好通过export重新声明环境变量,以免在定时任务等场合使用出现问题。
这里有个参考例子:https://blog.csdn.net/qq_19175749/article/details/50992242
END