shell脚本for循环


for...do...done (固定循环)
相对于while, until的循环方式是必须要符合某个条件的状态, for语法已经知道要进行几次循环!
for语句的语法如下:

              for var in con1 con2 con3 ...
              do
                程序段
              done
            
$var变量的变化:
1. 第一次循环, $var的值为con1 ;
2. 第二次循环, $var的值为con2 ;
3. 第三次循环, $var的值为con3 ;
4. .... 假设有三种动物,分别是dog, cat, elephant, 每一行输出There are dogs...之类的字样,则可以:
              [peter@study bin]$ vim show_animal.sh
              #!/bin/bash
              # Program:
              # Using for .... loop to print 3 animals
              # History:
              # 2015/07/17 INITroot First release

              PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
              export PATH
              for animal in dog cat elephant
              do
                echo "There are ${animal}s.... "
              done
            
系统上的各种账号都在/etc/passwd文件中的第一个字段, 由于不同的Linux系统上面的账号都不一样!
通过管线命令cut提取出账号名称后,以id分别检查用户的标识符与特殊参数, 此时实际去捉/etc/passwd并使用循环处理,就是一个可行的方案了!
程序可以如下:
              [peter@study bin]$ vim userid.sh
              #!/bin/bash
              # Program
              # Use id, finger command to check system account's information.
              # History
              # 2015/07/17 INITroot first release
              PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
              export PATH
              users=$(cut -d ':' -f1 /etc/passwd)  # 提取账号名称
              for username in ${users} # 开始循环进行!
              do
                id ${username}
              done
            
通过上面的脚就可以检查系统账号了!还可以用在每个账号的删除、重整上面!
换个角度来看,如果我现在需要一连串的数字来进行循环呢?
举例来说,我想要利用ping这个可以判断网络状态的指令, 来进行网络状态的实际侦测时,我想要侦测的网域是本机所在的 192.168.1.1~192.168.1.100,由于有100台主机,总不会要我在for后面输入1到100吧?此时你可以这样做:
              [peter@study bin]$ vim pingip.sh
              #!/bin/bash
              # Program
              # Use ping command to check the network's PC state.
              # History
              # 2015/07/17
              INITroot first release
              PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
              export PATH
              network="192.168.1" # 先定义一个网域的前面部分!
              for sitenu in $(seq 1 100) # seq 为 sequence(连续) 的缩写之意
              do
              # 底下的程序在取得 ping 的回传值是正确的还是失败的!
                ping -c 1 -w 1 ${network}.${sitenu} &> /dev/null && result=0 || result=1
              # 开始显示结果是正确的启动 (UP) 还是错误的没有连通 (DOWN)
                if [ "${result}" == 0 ]; then
                  echo "Server ${network}.${sitenu} is UP."
                else
                  echo "Server ${network}.${sitenu} is DOWN."
                fi
              done
            
执行后就可以显示出192.168.1.1~192.168.1.100共100部主机目前是否能与你的机器连通!
如果你的网域与所在的位置不同,则直接修改上头那个network的变量内容即可!
其实这个范例的重点在$(seq ..)!seq是连续(sequence)的缩写!代表后面接的两个数值是一直连续的!
如此一来,就能够轻松的将连续数字带入程序中啰!
除了使用 $(seq 1 100) 之外,也可以直接使用bash的内建机制来处理喔!
可以使用{1..100}取代$(seq 1 100)! 大括号内的前面/后面用两个字符,中间以两个小数点来代表连续出现的意思!
例如要持续输出 a, b, c...g, 就可以使用echo {a..g}这样的表示方式!
最后,让我们来玩判断式加上循环的功能!我想要让用户输入某个目录文件名, 然后我找出某目录内的文件名的权限:
              [peter@study bin]$ vim dir_perm.sh
              #!/bin/bash
              # Program:
              # User input dir name, I find the permission of files.
              # History:
              # 2015/07/17 INITroot First release
              PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
              export PATH
              # 1. 先看看这个目录是否存在啊?
              read -p "Please input a directory: " dir
              if [ "${dir}" == "" -o ! -d "${dir}" ]; then
                echo "The ${dir} is NOT exist in your system."
                exit 1
              fi
              # 2. 开始测试文件啰~
              filelist=$(ls ${dir})
              # 列出所有在该目录下的文件名
              for filename in ${filelist}
              do
                perm=""
                test -r "${dir}/${filename}" && perm="${perm} readable"
                test -w "${dir}/${filename}" && perm="${perm} writable"
                test -x "${dir}/${filename}" && perm="${perm} executable"
                echo "The file ${dir}/${filename}'s permission is ${perm}"
              done
            
利用这种方式,可以很轻易处理一些文件的特性。
for...do...done 的数值处理
for循环还有另外一种写法!语法如下:
              for (( 初始值; 限制值; 执行步阶 ))
              do
                程序段
              done
            
这种语法适合数值方式的运算,for后面的括号内的三串内容意义为:
初始值:某个变量在循环当中的起始值,直接以类似 i=1 设定好;
限制值:当变量的值在这个限制值的范围内,就继续进行循环。例如 i<=100;
执行步阶:每作一次循环时,变量的变化量。例如 i=i+1。
值得注意的是,在执行步阶的设定上,如果每次增加1,则可以使用类似i++的方式,亦即是i每次循环都会增加一的意思。
好,我们以这种方式来进行1累加到用户输入的循环吧!
              [peter@study bin]$ vim cal_1_100-2.sh
              #!/bin/bash 
              # Program: 
              # Try do calculate 1+2+....+${your_input} 
              # History: 
              # 2015/07/17 INITroot First release 

              PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin 
              export PATH read
              -p "Please input a number, I will count for 1+2+...+your_input: " nu 

              s=0 

              for (( i=1; i<=${nu}; i=i+1 ))
              do
                s=$((${s}+${i})) 
              done 

              echo "The result of '1+2+3+...+${nu}' is ==> ${s}" 
            
利用for则可以直接限制循环要进行几次呢!
搭配随机数与数组的实验
用脚本搭配随机数来告诉我们今天中午吃啥。 首先将全部的店家输入到一组数组当中,再通过随机数的处理,去取得可能的数值,再将搭配到该数值的店家秀出来即可!
让我们来实验看看:
              [peter@study bin]$ vim what_to_eat.sh
              #!/bin/bash 
              # Program: 
              # Try do tell you what you may eat. 
              # History: 
              # 2015/07/17 INITroot First release 
              PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin 
              export PATH
              eat[1]="卖当当汉堡"   # 写下收集到的店家!
              eat[2]="肯爷爷炸鸡" 
              eat[3]="彩虹日式便当" 
              eat[4]="越油越好吃大雅" 
              eat[5]="想不出吃啥学餐"
              eat[6]="太师父便当" 
              eat[7]="池上便当" 
              eat[8]="怀念火车便当" 
              eat[9]="一起吃泡面" 
              eatnum=9         # 需要输入有几个可用的餐厅数! 

              check=$(( ${RANDOM} * ${eatnum} / 32767 + 1 )) 
              echo "your may eat ${eat[${check}]}"
              
如果想要每次都秀出3个店家, 而且这个店家不能重复:
              [peter@study bin]$ vim what_to_eat-2.sh
              #!/bin/bash 
              # Program: 
              # Try do tell you what you may eat. 
              # History: 
              # 2015/07/17 INITroot First release
              PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin 
              export PATH 
              eat[1]="卖当当汉堡"
              eat[2]="肯爷爷炸鸡" 
              eat[3]="彩虹日式便当" 
              eat[4]="越油越好吃大雅" 
              eat[5]="想不出吃啥学餐" 
              eat[6]="太师父便当" 
              eat[7]="池上便当"
              eat[8]="怀念火车便当" 
              eat[9]="一起吃泡面" 
              eatnum=9 

              eated=0 

              while [ "${eated}" -lt 3 ]; do 
                check=$(( ${RANDOM} * ${eatnum} / 32767 + 1 )) 
                mycheck=0 
                if [ "${eated}" -ge 1 ]; then 
                  for i in $(seq 1 ${eated} ) 
                  do 
                    if [ ${eatedcon[$i]}==$check ]; then 
                      mycheck=1
                    fi 
                  done 
                fi 
                
                if [ ${mycheck}==0 ]; then
                  echo "your may eat ${eat[${check}]}" 
                  eated=$(( ${eated} + 1 )) 
                  eatedcon[${eated}]=${check} 
                fi 
              done
            
通过随机数、数组、循环与条件判断,可以做出很多特别的东西!还不用写传统程序语言!

initroot编辑整理,转载请注明www.initroot.com

100次点赞 100次阅读