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 VBird 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 VBird 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
VBird 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 VBird 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 VBird 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 VBird 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 VBird 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次阅读