shell循环之for、while、case

一、for循环:

概述:for循环根据指定的变量及变量取值列表,针对不同取值,重复执行命令,直到取值列表中的值全部用完,退出,for 循环适用于无规律的取值变量; 语法:for 变量名 in 变量取值列表 ;do 重复执行的命令(循环体),应用到变量名 done 变量取值列表: 命令:cat、seq、awk等命令的屏幕输出结果,例:A=$(cat 1.txt) 列表:直接在取值列表中定义内容 1.{a..z}、{A..Z}、{1..10},直接在取值列表中定义内容; 2.{a,b,c,d},直接在括号中写入内容; 3.a b c d ,不用括号,直接用空格隔开每个值; 数组: 定义数组:数组名=(第0个数组值 第1个数组值) 查看属组:echo ${数组名[数组的第n个位置]} ##显示数组中的第n个值 echo ${数组名[]} ##显示数组中的所有值 echo ${#数组名[]} ##显示数组中的值的个数 在脚本中使用数组:举例 #!/bin/bash A=(vsftpd named sshd) for i in ${A[*]};do /etc/init.d/$i start done

		案例一:
vi  user.txt
Zsan
Lisi
:wq

vi  useradd_for.sh
#!/bin/bash
Un=$(cat /root/user.txt)
for  i  in  $Un
do
useradd $i 
echo  123123 |passwd  --stdin $i
done
:wq

chmod  +x  useradd_for.sh
./useradd_for.sh

案例二:检查网络中存活主机
vi  chk_net_alive_host.sh
#!/bin/bash
read  -p "please your want chk net:" NET
for  i  in  $(seq  1  254)
do
ping  -c 2 $NET.$i  &&echo "$NET.$i is  up."
done

案例三:检查网络中存活主机
vi chk_net_alive_host2.sh
#!/bin/bash
#by liwenhu 20160924                    ##注释
ip=192.168.100.                         ##定义变量ip
for i in {1..254};do                    ##执行for循环语句,取值范围为1-254
  ping -c 2 -I eth0 $ip$i &>/dev/null     ##编写循环体,使用ping命令测试网络主机连通性
  if [ $? -eq 0 ];then                    ##使用if判断语句,判断ping命令的结果,若上条命令执行成功
    B=$(arping -I eth0 -f $ip$i |grep Unicast |awk '{print $5}')    ##若上条ping命令执行成功,证明此主机存在,定义变量B为此主机的MAC地址
	echo "$ip$i is starting MAC=$B"         ##输入结果和主机的MAC地址变量B到屏幕
  else                                    ##若ping命令执行不成功,证明主机不存在
	echo "$ip$i is stoping"
  fi
done

案例四:设置开机启动服务
vi  ck.list
crond
iptables
network
sshd

vi  chk_ser_onboot_for.sh
#!/bin/bash
SL=$(cat /root/ck.list)
for i in $SL
do
        /etc/init.d/$i status |grep pid
        if [ $? -ne 0 ];then
                /etc/init.d/$i restart
        fi
        chkconfig $i on
done

案例五:序列列表:
vi  for_list.sh
#!/bin/bash
for  i  in  {vsftpd,dhcpd,named}
do
/etc/init.d/$i  restart
chkconfig $i  on
done
for  i  in  {1..254}
do
ping -c 2 192.168.100.$i
done

案例六:数组列表:
vi for-arry.sh 
#!/bin/bash
A=(crond gpm iptables lvm2-monitor network rsyslog sshd udev-post)
echo ${A[1]}
echo ${A[5]}
echo A arry length is ${#A[*]}
for i in ${A[*]};do
chkconfig --list $i
done

案例七:双色球一等奖案例
vi shuangseqiu.sh
#!/bin/bash
>/tmp/num20.txt
for i in $(seq 1 20)
do expr $RANDOM % 33 + 1 >>/tmp/num20.txt
done
echo "第$(date +%Y)$(date +%s |tail -c 4)期开奖结果 开奖日期:$(date +%F)"
echo "==================================================================="
echo -e "\033[31m 红球:$(cat /tmp/num20.txt |sort -n |uniq |head -6 |xargs echo) \033[0m"
echo -e "\033[34m 篮球:$(expr $RANDOM % 16 + 1) \033[0m"

二、while循环:

概述:重复测试某个条件,只要条件成立,就重复执行命令,条件不成立,立即退出,自带判断; 语法:while 条件测试操作 ;do 重复执行的命令 done while循环体内常用的命令: let i++等于i=$(expr $i+1) ##变量i每执行一次循环则加1; expr $RANDOM % 100 ##取得100以内的随机数; sleep 2 ##休眠2秒,避免死循环真用过多的硬件资源; 退出while循环体的三种方式: 条件为假退出循环体,继续执行循环体以外的命令; exit退出脚本,循环体外的命令不会执行; break退出脚本中的循环体,继续执行循环体外的命令; 特殊条件表达式: true :当条件表达式为true时,那么代表条件表达式永远成立,为真; false:当条件表达式为false时,那么条件表达式永远为假;

		 案例一:创建用户
[root@ns bin]# cat useradd_while.sh
#!/bin/bash
PRE=stu
i=0
while [ $i -le 10 ];do
	useradd $PRE$i
	echo 123123 |passwd --stdin $PRE$i
	userdel -r $PRE$i
#i=$(expr $i + 1)
	let i++
done

案例二:猜价钱
[root@ns bin]# cat price_guess.sh 
#!/bin/bash
PRICE=$(expr $RANDOM % 1000)
TMS=0
echo "please insert a number like this(1-999)"
while true;do
	read -p "please give number:" INT
	let TMS++
if [ $INT -eq $PRICE ];then
	echo "your luckly. right! "
	echo "Your guess $TMS"
	exit 0
elif [ $INT -gt $PRICE ];then
	echo "Too High,try a again. "
else
	echo "Too low,try a again."
fi
done

案例三:测试退出命令
[root@ns bin]# cat die_while.sh 
#!/bin/bash
i=0
j=$(expr $RANDOM % 10)
while true;do
	echo $i
	let i++
	sleep 1   ##休眠1秒避免死循环产生
	if [ $i -eq $j ];then
		echo "ok,$j random"
	break      ##将break替换为exit执行后查看效果
fi
done

三、case循环:

概述:根据变量的值,顺序匹配模式,匹配后执行命令并结束,如果没有匹配的模式,则执行默认命令,执行成功后退出, 返回1,然后退出case; 语法:case "变量" in 模式1) 命令1 ;; 模式2) 命令2 ;; *) 默认命令 exit 1 ;; esac 模式:[0-9]:大括号内-表示一个连续的范围; A|B:|表示或;

		案例一:交互式定义变量匹配case
[root@ns bin]# cat key_hit_case.sh 
#!/bin/bash
read -p "Please hit a key:" KEY
case $KEY in
[a-z]|[A-Z])
	echo "your key is alph." 
	;;
[0-9])
	echo "your key is num."
	;;
*)
	echo "your key may be is #!@ and so on."
	exit 1
	;;
esac

案例二:位置变量匹配case
[root@ns bin]# cat prog_case.sh 
#!/bin/bash
#chkconfig: - 98 10
#description: A script for case by linuxfan.cn.
case $1 in
start)
	echo "hehe is starting."
	sleep 2
	;;
stop)
	echo "hehe is stoping."
	sleep 2
	;;
restart)
	$0 stop
	$0 start
	;;
*)
	echo "Usage:$0 {start|stop|restart}"
	exit 1
	;;
esac

案例三:查看vsftpd服务的控制脚本
[root@ns bin]# vim vsftpd
#!/bin/bash
#
### BEGIN INIT INFO
# Provides: vsftpd
# Required-Start: $local_fs $network $named $remote_fs $syslog
# Required-Stop: $local_fs $network $named $remote_fs $syslog
# Short-Description: Very Secure Ftp Daemon
# Description: vsftpd is a Very Secure FTP daemon. It was written completely from
#              scratch
### END INIT INFO

# vsftpd      This shell script takes care of starting and stopping
#             standalone vsftpd.
#
# chkconfig: - 60 50     ##设置允许级别和开、关机的启动顺序
# description: Vsftpd is a ftp daemon, which is the program \
#              that answers incoming ftp service requests.
# processname: vsftpd
# config: /etc/vsftpd/vsftpd.conf

# Source function library.
. /etc/rc.d/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network    

RETVAL=0
prog="vsftpd"

start() {    ##编写start函数,函数将许多的操作集成
        # Start daemons.

	# Check that networking is up.
	[ ${NETWORKING} = "no" ] && exit 1

	[ -x /usr/sbin/vsftpd ] || exit 1

        if [ -d /etc/vsftpd ] ; then
                CONFS=`ls /etc/vsftpd/*.conf 2>/dev/null`
                [ -z "$CONFS" ] && exit 6
                PROC_FAILED=0
                for i in $CONFS; do
                        site=`basename $i .conf`
                        echo -n $"Starting $prog for $site: "
                        daemon /usr/sbin/vsftpd $i
                        RETVAL=$?
                        echo
                        if [ $RETVAL -eq 0 ] && [ ! -f /var/lock/subsys/$prog ]; then
                                touch /var/lock/subsys/$prog
                        elif [ $RETVAL -ne 0 ]; then
                                ps -FC vsftpd | grep "$i" > /dev/null
                                RETVAL=$?
                                if [ $PROC_FAILED -eq 0 ] && [ $RETVAL -ne 0 ]; then
                                        PROC_FAILED=1
                                fi
                        fi
                done
                if [ $RETVAL -eq 0 ] && [ $PROC_FAILED -ne 0 ]; then
                        RETVAL=1
                fi
        else
                RETVAL=1
        fi
        return $RETVAL
}

stop() {
        # Stop daemons.
        echo -n $"Shutting down $prog: "
        killproc $prog
        RETVAL=$?
        echo
        [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$prog
        return $RETVAL
}

# See how we were called.
case "$1" in
  start)
        start
        ;;
  stop)
        stop
        ;;
  restart|reload)
        stop
        start
        RETVAL=$?
        ;;
  condrestart|try-restart|force-reload)
        if [ -f /var/lock/subsys/$prog ]; then
            stop
            start
            RETVAL=$?
        fi
        ;;
  status)
        status $prog
        RETVAL=$?
        ;;
  *)
        echo $"Usage: $0 {start|stop|restart|try-restart|force-reload|status}"
        exit 1
esac

exit $RETVAL