列表for循环
- 列表for循环的语法结构如下:
for variablein list #每一次循环,依次把列表list 中的一个值赋给循环变量
do #循环体开始的标志commands #循环变量每取一次值,循环体就执行一遍commands
done #循环结束的标志,返回循环顶部
列表 list 可以是命令替换、变量名替换、字符串和文件名列表(可包含通配符),每列表项以空格间隔。
for 循环执行的次数取决于列表 list 中单词的个数,可以省略in list,省略时相当于in"$@"。
- 例1:
#!/bin/bash
##filename:for1.sh
for x in centos ubuntu windows max
doecho "$x"
done
将字符串列表作为list,list包含centos ubuntu windows max,字符串以空格分割,for循环会把list列表依次输出
- 例子2,列表中包含"centos ubuntu" "windows 7 10"带空格的列表项,必须要用双引号括起来作为一个整体。
#!/bin/bash
##filename:for2.sh
for x in linux "centos ubuntu" windows "windows 7 10"
doecho "$x" ;
done
4. 例3,”== ls ==“是echo "$x"的输出结果,而40k这种信息是eval $x的输出结果(eval会将 $x 替换为没命令),然后执行命令,输出结果
#!/bin/bash
#filename:for3.sh
for x in ls "df -h" "du -sh"
doecho "==$x==" ; eval $x
done
5. 列表for循环执行流程:
首先将list的item1 赋给 variable,然后执行 do和done 之间的命令接着再将 list的item2赋给 variable,继续执行 do和done 之间的命令,如此循环,直到 list中的所有item值都已经用完才退出循环
不带列表for循环
- 不带列表的for循环执行是由用户指定参数和参数的个数,不带列表的for循环的基本格式:
不带列表的for循环的基本格式:
for variabledocommandcommand..done
其中 do和done之间的命令称为循环体,shell 会自动地将命令行输入的所有参数依次组织成列表,每次将一个命令行输入的参数显示给用户,直至所有的命令行中的参数都显示给用户。
- 例子1,所有输入的内容,都是通过脚本参数传递进去的,所以说,不带列表的 for循环其实是使用位置参数变量 "$ @"来传递 for 中的 list列表,其实相当于for 循环省略了in$@关键字。
#!/bin/bash
#filename:for4.sh
i=1
for day ; doecho -n "positional parameter $((i++)): $day "case $day in[Mm]on|[Tt]ue|[Ww]ed|[Tt]hu|[Ff]ri)echo " (weekday)";;[Ss]at[Ss]un)echo " (WEEKEND)";;*) echo "(Invalid weekday)";;esac
done[root@localhost tmp]# sh for4.sh Mon Tue wed Thu Fri sat Sun ok
positional parameter 1: Mon (weekday)
positional parameter 2: Tue (weekday)
positional parameter 3: wed (weekday)
positional parameter 4: Thu (weekday)
positional parameter 5: Fri (weekday)
positional parameter 6: sat (Invalid weekday)
positional parameter 7: Sun (Invalid weekday)
positional parameter 8: ok (Invalid weekday)
for循环举例
1.例1 所有文件名大写替换为小写
#!/bin/bash
##filename:for5.sh
for fname in * ;do
fn=$(echo $fname | tr A-Z a-z)
if [[ $fname != $fn ]] ; then mv $fname $fn ; fi
done
这个脚本的功能是将当前目录下的所有的大写文件名改为小写文件名。注意,脚本中的*表示当前目录下的文件和目录。首先使用命令替换生成小写的文件名,赋予新的变量f,如果新生成的小写文件名与原文件名不同,则改为小写的文件名。
2. 例2 读取/etc/passwd文件,依次输出ip段
#!/bin/bash
##filename:for6.sh
i=1
for username in `awk -F: '{print $1}' /etc/passwd`
doecho "Username $((i++)) : $username"
donefor suffix in $(seq 10)
doecho "192.168.0.${suffix}"
done
脚本实现两个功能:
第1个功能是读取/etc/passwd 文件,通过awk 获取第1列的内容作为 list,注意in 后面命令的写法,是个反引号,也就是键盘(Esc)下面的那个键,
第2个功能是通过seq 指定数字list,从1~10,然后依次输出一个IP 范围段
3. 例3 读取/etc/hosts内容for循环,执行ping
#!/bin/bash
#filename:for7_host.shfor host in $(cat /etc/hosts)
doif ping -c1 -w2 $host &>/dev/nullthenecho "host ($host) is active."elseecho "host ($host) is down."fi
done
这个脚本的功能是通过读取/etc/hosts 的内容作为 for循环的list,然后对读取到的内容进行ping 操作,如果能够ping通,显示active,否则显示DOWN。
4. 例4 循环ip列表,输出对应编号
#!/bin/bash
#filename:for8.sh
mynet="192.168.0"
for num in {1..6}
do
echo "IP Address $num: $mynet.$num"
donefor num in {1..10..2}
do
echo "Number: $num"
done
这个脚本是通过数值范围作为 for 循环的 lit 列表,1.6表示从1~6,而110…2是使用包含步长(increment)的数值范围作为for 循环的list,表示从1~10,每隔2个步长,执行脚本,输出如下:
5. 例5 批量添加用户
#!/bin/bash
#filename:for9.sh
for x in {1..10}
do
useradd user${x}
echo "centos"|passwd --stdin user${x}
chage -d 0 user${x}
done
这个脚本功能是批量添加10个Linux系统用户。需要注意的是,stdin 是接受echo后面的字符串作为密码,stdin 表示非交互,直接传入密码,passwd 默认是要用终端作为标准输入,加上–stdin 表示可以用任意文件做标准输入,于是这里用管道作为标准输入。最后的chage命令是强制新建用户第1次登录时修改密码。
break
break用于强行退出当前循环,格式如下:
break [n]
如果是嵌套循环,则 break 命令后面可以跟一数字 n,表示退出第n重循环(最里面的为第1重循环)。
1. 例1 break
#!/bin/bash
#filename:for10.sh
i=1
for day in Mon Tue Wed Thu Fri
doecho "Weekday $((i++)) : $day"if [ $i -eq 3 ]; then #脚本是当变量i等于3的时候退出循环,初始值为1。breakfi
done
continue
continue 用于忽略本次循环的剩余部分,回到循环的顶部,继续下一次循环,使用方法如下:
continue [n]
如果是嵌套循环,continue命令后面也可跟一数n,表示回到第n重循环的顶部。
1. 例1 continue
#!/bin/bash
##filename:for11.sh
i=1
for day in Mon Tue Wed Thu Fri Sat Sun
doecho -n "Day $((i++)) : $day"if [ $i -eq 7 -o $i -eq 8 ]; thenecho "(WEEKEND)"continuefiecho "(weekday)"
done
这个脚本的含义是变量i等于1~6时,输出对应的day变量的值,并显示(weekday),当变量i等于7或者8时,输出(WEEKEND)。注意这里的S((i++)),默认i等于1,当第1个i变量传递到f语句中时,i已经是2了。执行上面脚本,输出如下: