zoukankan      html  css  js  c++  java
  • Shell编程之for和select循环

    一、for和select循环

    1.for循环语法

    for 变量名 in 变量取值列表
    do
    	指令...
    done
    

    C语言型for循环

    for ((exp1; exp2; exp3))
    do
    	指令...
    done
    

    示例:

    for ((i=1;i<=3;i++))
    do
    	echo $i
    done
    

    说明:

    • 第一个是变量初始化
    • 第二个是变量范围
    • 第三个是变量自增或自减

    2.for循环实践

    (1)打印5、4、3、2、1这5个数字

    [root@codis-178 ~]# cat 11_1.sh 
    #!/bin/bash
    for num in 5 4 3 2 1
    do
    	echo $num
    done
    [root@codis-178 ~]# sh 11_1.sh 
    5
    4
    3
    2
    1
    
    其他方式:
    [root@codis-178 ~]# cat 11_1_1.sh 
    #!/bin/bash
    for num in {5..1}
    do
    	echo $num
    done
    

    (2)获取当前目录下的目录或文件,并将其作为变量列表打印输出

    [root@codis-178 ~]# mkdir -p /test/{text.txt,oldboy.txt,oldgirl.txt}
    [root@codis-178 ~]# ls -l /test/
    total 12
    drwxr-xr-x 2 root root 4096 Aug 23 10:42 oldboy.txt
    drwxr-xr-x 2 root root 4096 Aug 23 10:42 oldgirl.txt
    drwxr-xr-x 2 root root 4096 Aug 23 10:42 text.txt
    
    
    [root@codis-178 ~]# cat 11_2.sh 
    #!/bin/bash
    cd /test
    for filename in `ls`
    do
    	echo $filename
    done
    [root@codis-178 ~]# sh 11_2.sh 
    oldboy.txt
    oldgirl.txt
    text.txt
    

    (3)用for循环批量修改文件扩展名(把txt改成jpg)

    [root@codis-178 ~]# cat 11_3.sh 
    #!/bin/bash
    cd /test
    for filename in `ls|grep "txt$"`
    do
    	mv $filename `echo $filename|cut -d . -f1`.jpg
    done
    [root@codis-178 ~]# sh 11_3.sh 
    [root@codis-178 ~]# ls -l /test/
    total 12
    drwxr-xr-x 2 root root 4096 Aug 23 10:42 oldboy.jpg
    drwxr-xr-x 2 root root 4096 Aug 23 10:42 oldgirl.jpg
    drwxr-xr-x 2 root root 4096 Aug 23 10:42 text.jpg
    
    简介方法:
    [root@codis-178 ~]# rename "jpg" "gif" /test/*.jpg
    [root@codis-178 ~]# ls -l /test/
    total 12
    drwxr-xr-x 2 root root 4096 Aug 23 10:42 oldboy.gif
    drwxr-xr-x 2 root root 4096 Aug 23 10:42 oldgirl.gif
    drwxr-xr-x 2 root root 4096 Aug 23 10:42 text.gif
    

    3.企业应用

    (1)批量修改文件名,去掉"_finished"

    sed版
    [root@codis-178 ~]# cat 11_4.sh 
    #!/bin/bash
    cd /test
    for file in `ls *.log`
    do
    	mv $file `echo $file|sed 's/_finished//g'`
    done
    [root@codis-178 ~]# sh 11_4.sh 
    [root@codis-178 ~]# ll /test/*.log
    -rw-r--r-- 1 root root 0 Aug 23 11:03 /test/sku_102999_1.log
    -rw-r--r-- 1 root root 0 Aug 23 11:03 /test/sku_102999_2.log
    -rw-r--r-- 1 root root 0 Aug 23 11:03 /test/sku_102999_3.log
    -rw-r--r-- 1 root root 0 Aug 23 11:03 /test/sku_102999_4.log
    -rw-r--r-- 1 root root 0 Aug 23 11:03 /test/sku_102999_5.log
    
    rename版
    rename "_finished' "' *.jpg
    

    (2)在生产环境下,批量去掉测试数据所用的bd字符

    [root@codis-178 test]# ll
    total 0
    -rw-r--r-- 1 root root 0 Aug 23 11:09 bd502.html
    -rw-r--r-- 1 root root 0 Aug 23 11:09 bd503.html
    -rw-r--r-- 1 root root 0 Aug 23 11:09 bd504.html
    [root@codis-178 test]# rename "bd" "" *.html
    [root@codis-178 test]# ll
    total 0
    -rw-r--r-- 1 root root 0 Aug 23 11:09 502.html
    -rw-r--r-- 1 root root 0 Aug 23 11:09 503.html
    -rw-r--r-- 1 root root 0 Aug 23 11:09 504.html
    

    (3)通过脚本实现仅sshd、rsyslog、crond、network、sysstat服务在开机时启动

    方法一:
    for oldboy in `chkconfig --list|grep "3:on"|awk '{print $1}'|grep -vE "crond|network|sshd|rsyslog|sysstat"`;do chkconfig $oldboy off;done
    
    方法二:
    chkconfig --list|grep -vE "crond|network|sshd|rsyslog|sysstat"|awk '{print "chkconfig " $1 " off"}'|bash
    

    (4)打印九九乘法表

    [root@codis-178 ~]# cat 11_5.sh
    #!/bin/bash
    COLOR='E[47;30m'
    RES='E[0m'
    
    for num1 in `seq 9`
    do
    	for num2 in `seq 9`
    	do
    		if [ $num1 -ge $num2 ];then
    			if (((num1*num2)>9))
    				then
    					echo -en "${COLOR}${num1}x${num2}=$((num1*num2))${RES} "
    			else
    				echo -en "${COLOR}${num1}x${num2}=$((num1*num2))${RES}  "
    			fi
    		fi
    	done
    	echo " "
    done
    [root@codis-178 ~]# sh 11_5.sh 
    1x1=1   
    2x1=2  2x2=4   
    3x1=3  3x2=6  3x3=9   
    4x1=4  4x2=8  4x3=12 4x4=16  
    5x1=5  5x2=10 5x3=15 5x4=20 5x5=25  
    6x1=6  6x2=12 6x3=18 6x4=24 6x5=30 6x6=36  
    7x1=7  7x2=14 7x3=21 7x4=28 7x5=35 7x6=42 7x7=49  
    8x1=8  8x2=16 8x3=24 8x4=32 8x5=40 8x6=48 8x7=56 8x8=64  
    9x1=9  9x2=18 9x3=27 9x4=36 9x5=45 9x6=54 9x7=63 9x8=72 9x9=81
    

    (5)计算1到100之和

    [root@codis-178 ~]# cat 11_6.sh
    #!/bin/bash
    for ((i=1;i<=100;i++))
    do
    	((sum=sum+i))
    done
    echo $sum
    [root@codis-178 ~]# sh 11_6.sh
    5050
    

    4.for循环高级应用

    (1)实现MySQL分库备份脚本

    [root@codis-178 ~]# cat 11_7.sh 
    #!/bin/bash
    PATH="/app/mysql/bin:$PATH"
    DBPATH=/server/backup
    MYUSER=root
    MYPASS=oldboy123
    SOCKET=/data/3306/mysql.sock
    MYCMD="mysql -u$MYUSER -p$MYPASS -S $SOCKET"
    MYDUMP="mysqldump -u$MYUSER -p$MYPASS -S $SOCKET"
    [ ! -d "$DBPATH" ] && mkdir $DBPATH
    for dbname in `$MYCMD -e "show databases;"|sed '1,2d'|egrep -v "mysql|schema"`
    do
    	$MYDUMP $dbname|gzip >$DBPATH/${dbname}_$(date +%F).sql.gz
    done
    

    (2)实现MySQL分库分表备份脚本

    批量插入数据
    [root@codis-178 ~]# cat 11_7_1.sh 
    #!/bin/bash
    PATH="/app/mysql/bin:$PATH"
    DBPATH=/server/backup
    MYUSER=root
    MYPASS=oldboy123
    SOCKET=/data/3306/mysql.sock
    MYCMD="mysql -u$MYUSER -p$MYPASS -S $SOCKET"
    MYDUMP="mysqldump -u$MYUSER -p$MYPASS -S $SOCKET"
    for dbname in oldboy oldgirl xiaoting bingbing
    do
    	$MYCMD -e "use $dbname;create table test(id int,name varchar(16)); insert into test values(1,'testdata');"
    done
    
    备份脚本
    [root@codis-178 ~]# cat 11_7_2.sh 
    #!/bin/bash
    PATH="/app/mysql/bin:$PATH"
    DBPATH=/server/backup
    MYUSER=root
    MYPASS=oldboy123
    SOCKET=/data/3306/mysql.sock
    MYCMD="mysql -u$MYUSER -p$MYPASS -S $SOCKET"
    MYDUMP="mysqldump -u$MYUSER -p$MYPASS -S $SOCKET"
    [ ! -d "$DBPATH" ] && mkdir $DBPATH
    for dbname in `$MYCMD -e "show databases;"|sed '1,2d'|egrep -v "mysql|schema"`
    do
    	mkdir $DBPATH/${dbname}_$(date +%F) -p
    	for table in `$MYCMD -e "show tables from $dbname;"|sed '1d'`
    	do
    		$MYDUMP $dbname $table|gzip >$DBPATH/${dbname}_$(date +%F)/${dbname}_${table}.sql.gz
    	done
    done
    

    (3)批量检查Web服务是否正常,并发送相关邮件或手机报警

    [root@codis-178 ~]# cat 11_8.sh 
    #!/bin/bash
    path=/server/scripts
    MAIL_GROUP="1111@qq.com 2222@qq.com"
    PAGER+GROUP="18600338340 18911718229"
    LOG_FILE="/tmp/web_check.log"
    
    [ ! -d "$path" ] && mkdir -p $path
    function UrlList(){
    	cat >$path/domain.list<<EOF
    	http://www.baidu.com
    	http://www.163.com
    	http://www.sina.com
    EOF
    }
    function CheckUrl(){
    	FAILCOUNT=0
    	for ((i=1;$i<=3;i++))
    	do
    		wget -T 5 --tries=1 --spider $1 >/dev/null 2>&1
    
    		if [ $? -ne 0 ];then
    			let FAILCOUNT+=1
    		else
    			break
    		fi
    	done
    	return $FAILCOUNT
    }
    
    function MAIL(){
    	local SUBJECT_CONTENT=$1
    	for MAIL_USER in `echo $MAIL_FROUP`
    	do
    		mail -s "$SUBJECT_CONTENT " $MAIL_USER <$LOG_FILE
    	done
    }
    function PAGER(){
    	for PAGER_USER in `echo $PAGER_GROUP`
    	do
    		TITLE=$1
    		CONTACT=$PAGER_USER
    		HTTPGW=http://oldboy.sms.cn/smsproxy/sendsms.action
    		curl -d cdkey=5ADF-EFA -d password=OLDBOY -d phone=$CONTACT -d message="$TITLE[$2]" $HTTPGW
    	done
    }
    function SendMsg(){
    	if [ $1 -ge 3 ];then
    		RETVAL=1
    		NOW_TIME=`date +%Y-%m-%d %H:%M:%S`
    		SUBJECT_CONTENT="http://$2 is error,${NOW_TIME}"
    		echo -e "$SUBJECT_CONTENT" |tee $LOG_FILE
    		MAIL $SUBJECT_CONTENT
    		PAGER $SUBJECT_CONTENT $NOW_TIME
    	else
    		echo "http://$2 is ok"
    		RETVAL=0
    	fi
    	return $RETVAL
    }
    function main(){
    	UrlList
    	for url in `cat $path/domain.list`
    	do
    		CheckUrl $url
    		SendMsg $? $url
    	done
    }
    main
    

    (4)批量建10个账号,并设置密码(随机数,但必须是字符和数字混合)

    [root@codis-178 ~]# cat 11_9.sh 
    #!/bin/bash
    . /etc/init.d/functions
    user="xiaoda01"
    passfile="/tmp/user.log"
    for num in `seq -w 10`
    do
    	pass="`echo "test$RANDOM"|md5sum|cut -c 3-11`"
    	useradd $user$num &>/dev/null &&
    	echo -e "$user${num}:$pass" >>$passfile
    	if [ $? -eq 0 ];then
    		action "$user$num is ok" /bin/true
    	else
    		action "$user$num is fail" /bin/false
    	fi
    done
    echo -------------------------------
    chpasswd < $passfile
    cat $passfile && >$passfile
    [root@codis-178 ~]# sh 11_9.sh 
    xiaoda0101 is ok                                           [  OK  ]
    xiaoda0102 is ok                                           [  OK  ]
    xiaoda0103 is ok                                           [  OK  ]
    xiaoda0104 is ok                                           [  OK  ]
    xiaoda0105 is ok                                           [  OK  ]
    xiaoda0106 is ok                                           [  OK  ]
    xiaoda0107 is ok                                           [  OK  ]
    xiaoda0108 is ok                                           [  OK  ]
    xiaoda0109 is ok                                           [  OK  ]
    xiaoda0110 is ok                                           [  OK  ]
    -------------------------------
    xiaoda0101:1d2311ee7
    xiaoda0102:cfa830b4d
    xiaoda0103:82920ccf0
    xiaoda0104:c74f8c425
    xiaoda0105:f54760e68
    xiaoda0106:e6d4d939d
    xiaoda0107:364ca359e
    xiaoda0108:3d1a8afb0
    xiaoda0109:c7709971b
    xiaoda0110:6d8ab529c
    

    二、随机数生成方法

    1.系统变量$RANDOM(0~32767)

    [root@codis-178 ~]# echo $RANDOM
    11639
    [root@codis-178 ~]# echo $RANDOM
    26729
    

    2.通过openssl产生

    [root@codis-178 ~]# openssl rand -base64 8
    093jnyH8wW0=
    [root@codis-178 ~]# openssl rand -base64 16
    wbdEcXUylW09GcQZdPfumQ==
    [root@codis-178 ~]# openssl rand -base64 16
    mj2ZsMWN5kGcAxG/uvyeBw==
    

    3.通过时间date

    [root@codis-178 ~]# date +%s%N
    1503467625592127445
    [root@codis-178 ~]# date +%s%N
    1503467628842171721
    

    4.通过/dev/urandom配合cksum

    [root@codis-178 ~]# head /dev/urandom |cksum 
    3335560219 3028
    [root@codis-178 ~]# head /dev/urandom |cksum 
    1646715305 2885
    

    说明:
    /dev/urandom设备存储着系统当前运行环境的实时数据,可以看作系统在某个时候的唯一值。

    5.通过UUID

    [root@codis-178 ~]# cat /proc/sys/kernel/random/uuid 
    92062c1c-ccc3-4d4d-939a-827b6f93f3d9
    [root@codis-178 ~]# cat /proc/sys/kernel/random/uuid 
    5a274f33-ad1c-4ad1-bc86-d6b472dec70a
    [root@codis-178 ~]# cat /proc/sys/kernel/random/uuid 
    7178879c-fcf7-4acb-8b43-5936bc403336
    

    说明:
    UUID码是通用唯一识别码,是一个软件建构的标准,目的是让分布式系统中的所有元素都能有唯一的辨识信息。

    6.使用expect附带的mkpasswd

    usage: mkpasswd [args] [user]
      where arguments are:
        -l #      (length of password, default = 9)  密码长度
        -d #      (min # of digits, default = 2)  数字的数量
        -c #      (min # of lowercase chars, default = 3)  小写字母的数量
        -C #      (min # of uppercase chars, default = 2)  大写字母的数量
        -s #      (min # of special chars, default = 1)  特殊字符的数量
        -v        (verbose, show passwd interaction)
        -p prog   (program to set password, default = passwd)
    	
    [root@codis-178 ~]# mkpasswd -l 16 -d 4 -c 4 -C 4 -s 4
    04r-v3"zIa5G??LC
    [root@codis-178 ~]# mkpasswd -l 16 -d 4 -c 4 -C 4 -s 1
    HHldb8zZJ%0mh00r
    [root@codis-178 ~]# mkpasswd -l 16 -d 4 -c 4 -C 4 -s 4
    D#uC{1#17kVyjM2
    

    总结

    统一格式化:使用md5sum|cut -c 2-10

    三、select循环

    1.select语法

    select 变量名 [ in 菜单取值列表 ]
    do
    	指令...
    done
    

    l00

    2.select循环的作用

    创建菜单

    3.实现

    [root@codis-178 ~]# cat 11_10.sh 
    #!/bin/bash
    select name in oldboy oldgirl tingting
    do
    	echo $name
    done
    [root@codis-178 ~]# sh 11_10.sh 
    1) oldboy
    2) oldgirl
    3) tingting
    #? 1
    oldboy
    #? 2
    oldgirl
    #? 3
    tingting
    

    调整select菜单项的默认提示符及利用select变量打印数字序号

    [root@codis-178 ~]# cat 11_10_1.sh 
    #!/bin/bash
    PS3="please select a num from menu:"
    select name in oldboy oldgirl tingting
    do
    	echo -e "I guess you selected the menu is:
     $REPLY) $name"
    done
    [root@codis-178 ~]# sh 11_10_1.sh 
    1) oldboy
    2) oldgirl
    3) tingting
    please select a num from menu:1
    I guess you selected the menu is:
     1) oldboy
    please select a num from menu:2
    I guess you selected the menu is:
     2) oldgirl
    please select a num from menu:3
    I guess you selected the menu is:
     3) tingting
    
  • 相关阅读:
    hbase分布式集群搭建
    hadoop分布式集群搭建
    cobbler koan自动重装系统
    nginx基础整理
    cobbler 自定义安装系统
    cobbler 自定义私有yum源
    cobbler自动安装系统
    [转]10+倍性能提升全过程--优酷账号绑定淘宝账号的TPS从500到5400的优化历程
    服务器性能调优(netstat监控大量ESTABLISHED连接与Time_Wait连接问题)
    LINUX下解决netstat查看TIME_WAIT状态过多问题
  • 原文地址:https://www.cnblogs.com/tongxiaoda/p/7454647.html
Copyright © 2011-2022 走看看