您的位置:首页 > 运维架构 > Shell

bash编程初体验之for

2016-08-24 16:32 330 查看

bash编程初体验之for

for

while

until

概述

本文将介绍以for为代表的循环语句在shell 脚本中的应用,常见的循环语句有for, while, until,作为循环语句,顾名思义,它就是重复地做一件事,直到满足某一条件而退出;另外,还有两个循环控制语句continue与break来配合循环语句,以实现临时中断或跳出循环的功能;以下为for, while, until的知识点提炼:
for, while, until

进入条件
for: 列表元素非空
while:条件测试结果为真
until:条件测试结果为假
退出条件
for: 列表元素遍历完成
while: 条件测试结果为假
until: 条件测试结果为真

循环控制语句:
continue: 表示提前结束本轮循环,而直接进入下一轮循环的判断;
break: 提前跳出循环
其中,for循环有两种风格,一种给个变量,让其去遍历列表;一种是类似C语言的形式,整个循环就是控制变量,当然这个形式的for循环一般都可写成while循环;while与until形式是一样的,只是进入与退出循环的条件相左而已,它们与read语句结合可达到逐行修改某一文件的功能,其实就是用read以输入重定向的方式读取文件的每一行,让while去遍历每一行,且满足某条件时执行相应的语句;当然until也是类似的;for循环中列表的生成方法:
(1) 直接给出列表
(2) 整数列表:
(a) {start..end}
(b) $(seq[start [step]] end)
(3) 返回列表的命令    $(COMMAND)(4) 使用glob,如:*.sh
(5) 变量引用;    $@, $*
for 变量名 in 列表;do
循环体
done

执行机制:
依次将列表中的元素赋值给“变量名”; 每次赋值后即执行一次循环体; 直到列表中的元素耗尽,循环结束。
关于双小括号法的for循环
双小括号方法,即((…))格式,也可以用于算术运算
双小括号方法也可以使bash Shell实现C语言风格的变量操作,如:
[root@centos7 ~]#i=8
[root@centos7 ~]#((i++))
[root@centos7 ~]#echo $i
9
[root@centos7 ~]#
for循环的特殊格式:for ((控制变量初始化;条件判断表达式;控制变量的修正表达式))do
循环体
done
控制变量初始化:仅在运行到循环代码段时执行一次
控制变量的修正表达式:每轮循环结束会先进行控制变量修正运算,而后再做条件判断

亦即:    for ((: for (( exp1; exp2; exp3 )); do COMMANDS; done
等价于
(( EXP1 ))
while (( EXP2 )); do
COMMANDS
(( EXP3 ))
while循环:
while CONDITION	do
循环体
循环控制变量修正表达式
done

CONDITION:循环控制条件;进入循环之前,先做一次判断;每一次循环之后会再次做判断;
条件为“true”,则执行一次循环;直到条件测试状态为“false”终止循环;
因此:CONDTION一般应该有循环控制变量;而此变量的值会在循环体不断地被修正。
until循环:
until CONDITION; do
循环体
done
循环控制语句:continue
用于循环体中continue
:提前结束第N层的本轮循环,而直接进入下一轮判断;最内层为第1层
while CONDTIITON1; do
CMD1
...
if CONDITION2; then
continue
fi
CMDn
...
done
循环控制语句:break
用于循环体中break
:提前结束第N层循环,最内层为第1层
while CONDTIITON1; do
CMD1
...
if CONDITION2; then
break
fi
CMDn
...
done
创建无限循环:
while true; do
循环体
done

until false; do
循环体
done

for循环练兵场

1、判断/var/log目录下所有文件的类型。
1 #!/bin/bash
2 #
3
4 for filename in /var/log/*
5 do
6         if [ -f $filename ]
7         then
8                 echo "Common file."
9         elif [ -d $filename ]
10         then
11                 echo "Birectory file."
12         elif [ -L $filename ]
13         then
14                 echo "Symlic link file."
15         elif [ -b $filename ]
16         then
17                 echo "Block spelic file."
18         elif [ -S $filename ]
19         then
20                 echo "Char spelic file."
21         else
22                 echo "Unknow file."
23         fi
24 done


当然,如果已经编写好了判断文件类型的脚本,还可以直接调用:
#!/bin/bash
#
# 调用filetype.sh这个脚本
for filename in /var/log/*do
echo $filename |./filetype.sh
done
2、添加10个用户user1-user10,密码同用户名。
1 #!/bin/bash
2 #
3 while [[ $1 -lt 1 ]]
4 do
5         read -p "Enter a username: " user
6         if [ -n user ]  #判断是否为非空
7         then
8                 break 2
9         fi
10 done
11
12 for i in {1..10}
13 do
14         useradd ${user}${i}
15         echo ${user}${i} |passwd --stdin ${user}${i} &> /dev/null
16         echo "Add ${user}${i} finished."
17 done


3、/etc/rc.d/rc3.d目录下分别有多个以K开头和以S开头的文件;分别读取每个文件,以K开头的文件输出为文件加stop,以S开头的文件输出为文件名加start; “K34filename stop” “S66filename start”
1 #!/bin/bash
2 #
3 for i in `ls /etc/rc.d/rc3.d`
4 do
5         KS_file=`echo $i |cut -c1`
6
7         case $KS_file in
8         K)
9                 echo -e "$i\tstop"
10                 ;;
11         S)
12                 echo -e "$i\tstart"
13                 ;;
14         *)
15                 echo "Unknow file."
16                 ;;
17         esac
18 done


4、写一个脚本,提示输入正整数n的值,计算1+2+3+…n的总和。
1 #!/bin/bash
2 #
3 read -p "Please input a integer: " int
4 declare -i sum=0
5
6 for i in $(seq 1 $int)
7 do
8         sum=$[$sum+$i]
9 done
10 echo "sum is $sum"


当然,也可以这样:
1 #!/bin/bash
2 #
3 read -p "Please input a integer: " int
4 declare -i sum=0
5
6 for ((i=0;i<=$int;i++))  7 do
8         sum+=$i
9 done
10 echo "sum is $sum"
5、打印九九乘法表
1 #!/bin/bash
2 #
3
4 for j in {1..9} 5 do
6         for i in $(seq 1 $j) 7         do
8                 echo -n -e "${i}X${j}=$[$i*$j]\t"
9         done
10         echo
11 done


当然,也可以这样:
1 #!/bin/bash
2 #
3 # for的特殊用法
4 for ((j=1;j<=9;j++)) 5 do
6         for ((i=1;i<=$j;i++))
7         do
8                 echo -n -e "${i}X${j}=$[$i*$j]\t"
9         done
10         echo
11 done
6.写一个脚本,提示请输入网络地址,如192.168.0.0,判断输入的网段中主机在线状态。
1 #!/bin/bash
2 #
3 read -p "Please input a network address: " ip
4
5 Cutip=$(echo $ip |cut -d. -f1-3). # 此处可按实际网段修改,注意后面要加个.
6
7 if echo $ip |grep -q -E '\<((([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([1-9]?[0-9]|1[0-9]{
2}|2[0-4][0-9]|25[0-5]))\>' &> /dev/null
8 then
9         for ((i=105;i<110;i++))  # i可按实际需求修改,此处只测试5个ip,譬如i=100;i<=255;i++
10         do
11                 if  ping -c 1 -W 1 ${Cutip}${i} &> /dev/null
12                 then
13                         echo "${Cutip}${i} is up"
14                 else
15                         echo "${Cutip}${i} is down"
16                 fi
17         done
18 else
19         echo "$ip is invaild."
20 fi


7.写个脚本,实现如下字样
*
***
******
********
分析:
星号:每行的星号都是从1开始的奇数递增,如果高当前行为n,则每行的星号个数为:2n-1
空格:如果设总行数为N,则每一行中空格的个数为:N-n
1 #!/bin/bash
2 #
3 read -p  "Please input a number: " N  # 代表要打印的行数
4
5 if echo $n |grep -E "[0-9]*" &> /dev/null
6 then
7         for n in `seq 1 $N`  # n代表当前行
8         do
9                 for ((k=(N-n);k>0;k--))   # k代表空格
10                 do
11                         echo -n  " "
12                 done
13                 for ((s=1;s<=(2*n-1);s++)) # s代表星号
14                 do
15                         echo -n "*"
16                 done
17                 echo
18         done
19 else
20         echo "number is invalid."
21 fi


8.打印国际象棋棋盘国际象棋,就是一个八行八列,两种颜色相间的一个棋盘,如下图:

思路一:找出每个颜色块所对应的坐标,其所在行记为l,其所在列记为n,发现(l+n)%2如果为零,则为一种颜色A,如果(l+n)不为0,则为另一种颜色B;思路二:奇数行(列)的颜色布局是相同的,偶数行(列)的颜色布局是相同的;其中,奇数行里面,奇数列对应的颜色是A,偶数列对应的颜色是B; 偶数行里面,奇数列对应的颜色是B,偶数表对应的颜色是A.思路一代码:
1 #!/bin/bash
2 #
3 for ((l=1;l<=8;l++))   # l为行数
4 do
5         for ((n=1;n<=8;n++))  # n为列数
6         do
7                 if [ $[($l+$n)%2] -eq 0 ]
8                 then
9                         echo -ne "\e[41;1m  \e[0m"  # 打印时要加参数 -n,即不换行
10                 else
11                         echo -ne "\e[43;1m  \e[0m"
12                 fi
13         done
14         echo
15 done


思路二代码:
1 #!/bin/bash
2 #
3 for ((l=1;l<=8;l++))  # l代表行
4 do
5         if [ $[$l%2] -eq 0 ]
6         then
7                 for ((n=1;n<=8;n++)) # n代表列
8                 do
9                         if [ $[$n%2] -eq 0 ]
10                         then
11                                 echo -ne "\e[45;1m  \e[0m"
12                         else
13                                 echo -ne "\e[46;1m  \e[0m"
14                         fi
15                 done
16         else
17                 for ((n=1;n<=8;n++))
18                 do
19                         if [ $[$n%2] -eq 1 ]
20                         then
21                                 echo -ne "\e[45;1m  \e[0m"
22                         else
23                                 echo -ne "\e[46;1m  \e[0m"
24                         fi
25                 done
26         fi
27         echo
28 done


while 练兵场

1、求100以内所有正整数之和
1 #!/bin/bash
2 #
3
4 declare -i sum=0
5 declare -i i=1
6
7 while [ $i -le 100 ] 8 do
9         let sum+=$i
10         let i++11 done12 echo "1-100之和为 $sum"


2、通过ping命令探测10.1.249.1-254范围内的所有主机的在线状态,统计在线主机和离线主机各多少
1 #!/bin/bash
2 #
3 read -p "Enter 10.1.249.0网段或ip: " ip  4
5 Cutip=$(echo $ip |cut -d. -f1-3)   # 注意此处的变量赋值
6 declare -i i=100  # 此处可按实际需要修改
7 declare -i uphosts=0
8 declare -i downhosts=0
9
10 if echo $ip |grep -q -E '\<((([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([1-9][0-9]?|1[0-9]{
2}|2[0-4][0-9]|25[0-5]))\>'
11
12 then
13 while [ $i -le 110 ]; do # 此处可按实际需要修改
14         pip=$Cutip.$i  # 此变量不能定义在while循环之外
15         ping -c 1 -W 1 $pip &> /dev/null
16
17         if [ $? -eq 0 ]; then
18                 echo "$pip is up."
19                 let uphosts++
20         else
21                 echo "$pip is down."
22                 let downhosts++
23         fi
24         let i++ 25 done
26 fi
27 echo "The online hosts sum is $uphosts."
28 echo "Then downline hosts sum is $downhosts."


3、打印九九乘法表
1 #!/bin/bash
2 #
3 declare -i j=1
4
5 while [ $j -le 9 ]
6 do
7         declare -i i=1
8         while [ $i -le $j ]
9         do
10                 echo -n -e "${i}X${j}=$[$i*$j]\t"
11         let i++
12         done
13         echo
14 let j++
15 done


当然,也可以这样:
1 #!/bin/bash
2 #
3 ((j=1))
4 while ((j<=9)); do
5         ((i=1))
6         while ((i<=$j)); do
7                 echo -en "${i}X${j}=$[$i*$j]\t"
8                 ((i++))
9         done
10         echo
11         ((j++))
12 done
4、利用变量RANDOM生成10个随机数字,输出这个10数字,并显示其中的最大者和最小者
1 #!/bin/bash
2 #
3 declare -i max=0
4 declare -i min=10
5 ((i=1))
6 while ((i<=10)); do
7         random=$[$RANDOM%10+1]
8         ((i++))
9         echo $random
10         [ $min -gt $random ] && min=$random
11         [ $max -lt $random ] && max=$random
12 done
13
14 echo "MAX is $max"
15 echo "MIN is $min"


5、打印国际象棋棋盘
1 #!/bin/bash
2 #
3 declare -i n  # n代表行
4 declare -i l  # l代表列
5
6 ((n=1))
7 while ((n<=8)); do
8         ((l=1))
9         while ((l<=8)); do
10                 if [ $[($n+$l)%2] -eq 0 ]; then
11                         echo -en "\e[44;1m  \e[0m"
12                 else
13                         echo -en "\e[47;1m  \e[0m"
14                 fi
15                 ((l++))
16         done
17         echo
18         ((n++))
19 done


1 #!/bin/bash
2 #
3 declare -i n    # n代表行
4 declare -i i    # i代表列
5
6 n=1
7 while ((n<=8)); do
8         if [ $[$n%2] -eq 0 ]; then
9                 i=1
10                 while ((i<=8)); do
11                         if [ $[$i%2] -eq 0 ]; then
12                                 echo -en "\e[47;1m  \e[0m"
13                         else
14                                 echo -en "\e[46;1m  \e[0m"
15                         fi
16                         ((i++))
17                 done
18         else
19                 i=1
20                 while ((i<=8)); do
21                         if [ $[$i%2] -eq 1 ]; then
22                                 echo -en "\e[47;1m  \e[0m"
23                         else
24                                 echo -en "\e[46;1m  \e[0m"
25                         fi
26                         ((i++))
27                 done
28         fi
29         ((n++))
30 echo
31 done


until练兵场

1、打印九九乘法表
1 #!/bin/bash
2 #
3 declare -i j=1
4
5 until [ $j -gt 9 ] 6 do
7         i=1
8         until [ $i -gt $j ]
9         do
10                 echo -n -e "${i}X${j}=$[$i*$j]\t"
11         let i++
12         done
13         echo
14 let j++
15 done


2、求1-100之和
1 #!/bin/bash
2 #
3
4 declare -i sum=0
5 declare -i i=100
6
7 until [ $i -lt 1 ]
8 do
9         let sum+=$i
10         let i--
11 done
12 echo "sum is $sum"



3、随机生成10以内的数字,实现猜字游戏,提示比较大或小,相等则退出。
1 #!/bin/bash
2 #
3 read -p "Please input 1-10之间的整数:" num
4 random=$[$RANDOM%10+1]
5
6 if echo $num |grep -q -E '\<([1-9]|[0]?)\>'; then
7         until [ $num -eq $random ]; do
8                  [ $num -gt $random ] &&  echo "This num is too big,please give a dot."
9                  [ $num -lt $random ] &&  echo "This num is too dot,please give a big."
10                  read -p "Please input 1-10之间的整数:" num
11         done
12
13         echo "Congratulations, you guessed right."
14 else
15         echo "num is invalid."
16 fi



本文其它案例会持续更新......
止战2016.8.24
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  for while until