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]:提前结束第N层的本轮循环,而直接进入下一轮判断;最内层为第1层 while CONDTIITON1; do CMD1 ... if CONDITION2; then continue fi CMDn ... done
循环控制语句:break
用于循环体中break [N]:提前结束第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
原创文章,作者:Liansir,如若转载,请注明出处:http://www.178linux.com/39741