Python 风格的for循环


Python 风格的 for in 循环的用法如下:

for variable in value_list
do
    statements
done

variable 表示变量,value_list 表示取值列表,in 是 Shell 中的关键字。

每次循环都会从 value_list 中取出一个值赋给变量 variable,然后进入循环体(do 和 done 之间的部分),执行循环体中的 statements。直到取完 value_list 中的所有值,循环就结束了。

Shell for in 循环举例:

#!/bin/bash
sum=0
for n in 1 2 3 4 5 6
do
    echo $n
     ((sum+=n))
done
echo "The sum is "$sum

运行结果:
1
2
3
4
5
6
The sum is 21

注意大括号的列表内容的用法

[root@localhost ~]# echo 192.168.1.{5..1}
192.168.1.5 192.168.1.4 192.168.1.3 192.168.1.2 192.168.1.1
[root@localhost ~]# echo {a..f}
a b c d e f

获取当前目录下的目录名作为变量列表打印输出

[root@localhost ~]# ls
for-1.sh for-2-1.sh for-2.sh for-3.sh
[root@localhost ~]# cat for-3.sh
for n in `ls`
do
echo $n
done

对 value_list 的说明


取值列表 value_list 的形式有多种,你可以直接给出具体的值,也可以给出一个范围,还可以使用命令产生的结果,甚至使用通配符,下面我们一一讲解。

1) 直接给出具体的值

可以在 in 关键字后面直接给出具体的值,多个值之间以空格分隔,比如1 2 3 4 5、"abc" "390" "tom"等。 上面的代码中用一组数字作为取值列表,下面我们再演示一下用一组字符串作为取值列表:

#!/bin/bash
for str in "test1" "test2" "test3" 
do
echo $str
done

运行结果:
test1
test2
test3

2) 给出一个取值范围

给出一个取值范围的具体格式为:

{start..end}

start 表示起始值,end 表示终止值,注意中间用两个点号相连,而不是三个点号。这种形式只支持数字和字母。例如,计算从 1 加到 100 的和:

#!/bin/bash
sum=0
for n in {1..100}

do
((sum+=n))
done

echo $sum

运行结果:
5050

再如,输出从 A 到 z 之间的所有字符:

#!/bin/bash

for c in {A..z}
do
printf "%c" $c
done

输出结果:
ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz

可以发现,Shell 是根据 ASCII 码表来输出的。

3) 使用命令的执行结果

使用反引号``或者$()都可以取得命令的执行结果。例如,计算从 1 到 100 之间所有偶数的和:

#!/bin/bash

sum=0

for n in $(seq 2 2 100)
do
((sum+=n))
done

echo $sum

运行结果:
2550

seq 是一个 Linux 命令,用来产生某个范围内的整数,并且可以设置步长。seq 2 2 100表示从 2 开始,每次增加 2,到 100 结束。 再如,列出当前目录下的所有 Shell 脚本文件:

#!/bin/bash

for filename in $(ls *.sh)
do
echo $filename
done

运行结果:
demo.sh
test.sh
abc.sh

exit 退出当前 shell 程序。

[root@localhost ~]# cat exit-1.sh
#!/bin/sh
for((i=0; i<=5; i++))
do
if [ $i -eq 3 ];then
exit 1
fi
echo $i
done
echo "ok"

[root@localhost ~]# sh exit1.sh
0
1
2

提示:可以看到 i 等于 3 及以后的循环没有执行,而且循环外的 echo 也没有执行。

企业面试题: 写一个脚本,实现判断 192.168.1.0/24 网络里,当前在线用户的 IP 有哪些。

[root@localhost ~]# cat .sh
#!/bin/bash
. /etc/init.d/functions

for I in `seq 1 255`
do
  ping -c 1 192.168.1.$I &>/dev/null
  if [ $? -eq 0 ]
    then
      action "10.0.0.$I is up." /bin/true
    else
      action "10.0.0.$I is down." /bin/false
  fi
done