在这章节中,我们会讨论Unix系统里面的Shell循环。循环就是一个可以让你重复执行某一个命令的编程方法。在这章节中,我们会介绍可用于Shell程序员的以下类型的循环 -
while循环
for循环
until循环
select循环
你将会在不同情况下使用最适当的循环方法。例如,while循环执行一个命令直到给的条件保持为真;until循环执行一个命令知道条件为真。
一旦你有了良好的编程实践,你将获得专业知识,从而在不同的情况下使用适当的循环方法。在这里,while和for循环普遍于其它的编程语言,比如C,C++和PERL等等。
while循环
while循环使您能够重复执行一组命令,直到条件不为真。while循环通常用于反复操作变量的值。
句法
while command
do
Statement(s) to be executed if command is true
done
上面的那个句法,程序会先计算 command 语句的结果,如果返回的结果是 true,则会执行 statement(s) 里面的程序。如果 command 返回的结果是 false,则不执行任何语句。并且程序将跳至 done 语句之后的下一行。
例子
下面是一个简单的示例,使用 while 循环打印数字 0 到 9
#!/bin/sh
a=0
while [ $a -lt 10 ]
do
echo $a
a=`expr $a + 1`
done
上面的程序执行后,将收到以下结果:
0
1
2
3
4
5
6
7
8
9
变量 a 的初始值为 0,每次执行此循环时,都会检查变量 a 的值,以查看其值是否小于 10。如果 a 的值小于 10,就显示 a 的当前值,然后将 a 递增 1。
for 循环
for 循环对项目列表进行操作,它重复执行列表中的每一个项目的命令集。
句法
for var in word1 word2 ... wordN
do
Statement(s) to be executed for every word.
done
上面的代码,var 是变量的名称,而 word1 到 wordN 是由空格(单词)分隔的字符序列。每次执行 for 循环时,变量 var 的值将设置为单词列表 word1 至 wordN 中的下一个单词。
示例
下面是一个简单的例子,给定一个数字列表,使用 for 循环遍历 −
#!/bin/sh
for var in 0 1 2 3 4 5 6 7 8 9
do
echo $var
done
执行脚本后,您将获得以下结果 −
0
1
2
3
4
5
6
7
8
9
下面的例子将显示所有以 .bash 开头的文件,此段脚本对你的家目录同样有效。我们从我的根目录执行这个脚本 −
#!/bin/sh
for FILE in $HOME/.bash*
do
echo $FILE
done
以上脚本会产生以下结果 −
/root/.bash_history
/root/.bash_logout
/root/.bash_profile
/root/.bashrc
until 循环
while 循环非常适合在某些条件为真时需要执行一组命令的情况。有时则需要执行一组命令,直到条件为真为止。
语法
until command
do
Statement(s) to be executed until command is true
done
在这里, Shell 命令 被评估。如果结果值为 false ,则执行给定的 语句 。 如果 命令 结果值是 true ,则不会执行任何语句,程序将跳到完成语句之后的下一行。
示例
这里有一个简单的例子,它使用 until 循环来显示零到九的数字 −
#!/bin/sh
a=0
until [ ! $a -lt 10 ]
do
echo $a
a=`expr $a + 1`
done
脚本执行后,您将获得以下结果 −
0
1
2
3
4
5
6
7
8
9
select 循环
select 循环提供了一种简单的方法来创建一个编号菜单,用户可以从中选择选项。这种场合适用于当您需要用户从选择列表中选择一个或多个项时。
语法
select var in word1 word2 ... wordN
do
Statement(s) to be executed for every word.
done
这里 var 是变量的名称, word1 到 wordN 是由空格(或者单词)分隔的字符序列。每次执行 for 循环时,变量 var 的值都会被设置为单词列表中的下一个单词,即从 word1 到 wordN 。
对于每个选择,将在循环中执行一组命令。 select 循环是在 ksh 中引入的,已被 bash 兼容,但在 sh 环境中无效。
Example
这里有一个简单的例子,让用户选择一种饮料 −
#!/bin/ksh
select DRINK in tea cofee water juice appe all none
do
case $DRINK in
tea|cofee|water|all)
echo "Go to canteen"
;;
juice|appe)
echo "Available at home"
;;
none)
break
;;
*) echo "ERROR: Invalid selection"
;;
esac
done
由 select 循环呈现的菜单如下所示 −
$./test.sh
1) tea
2) cofee
3) water
4) juice
5) appe
6) all
7) none
#? juice
Available at home
#? none
$
您可以采用下面的方法通过更改变量 PS3 的值来更改 select 循环的提示信息 −
$PS3 = "Please make a selection => " ; export PS3
$./test.sh
1) tea
2) cofee
3) water
4) juice
5) appe
6) all
7) none
Please make a selection => juice
Available at home
Please make a selection => none
$
嵌套循环
所有循环都支持嵌套,这意味着您可以将一个循环放入另一个类似的循环或不同的循环中。只要您需要,嵌套层数可以任意的多。
下面是嵌套的 while 循环示例。其它循环可以基于编程需求以类似的方式嵌套 −
while 嵌套循环
可以使用 while 循环作为另一个 while 循环体的一部分。
语法
while command1 ; # 这是第一层循环,即外层循环
do
Statement(s) to be executed if command1 is true
while command2 ; # 这是第二层循环,即内层循环
do
Statement(s) to be executed if command2 is true
done
Statement(s) to be executed if command1 is true
done
示例
下面是嵌套循环的一个简单例子。让我们在循环中添加另一个您通常数到 9 的倒计数循环−
#!/bin/sh
a=0
while [ "$a" -lt 10 ] # 这是第一层循环
do
b="$a"
while [ "$b" -ge 0 ] # 这是第二层循环
do
echo -n "$b "
b=`expr $b - 1`
done
echo
a=`expr $a + 1`
done
这将产生以下结果。 需要注意的是 echo-n 在这里的用处是什么。 这里的 -n 选项是让 echo 避免换行。
0
1 0
2 1 0
3 2 1 0
4 3 2 1 0
5 4 3 2 1 0
6 5 4 3 2 1 0
7 6 5 4 3 2 1 0
8 7 6 5 4 3 2 1 0
9 8 7 6 5 4 3 2 1 0