Bash shell 流程控制——循环控制

循环控制结构

循环控制是很多编程语言中的重要控制结构,主要用于控制重复执行的代码块。在Bash Shell中循环控制有3个命令,分别是forwhileuntil。同时也有breakcontinue两个命令用于干预循环结构的执行。下面首先讲解命令的使用语法,然后讲几点高级用法或者说特殊的使用方法。

基本语法

for

for循环的基本语法是:

1
2
3
4
for var in list  # 可以与do放在一行,但是要用一个分号隔开,如下
do # for var in list; do
commands
done

例如:

1
2
3
4
5
6
7
8
9
list="I LOVE YOU"
for var in $list # 或者直接是:for var in I LOVE YOU
do
echo $var
done
# 将会输出:
# I
# LOVE
# YOU

while

while循环的基本语法是:

1
2
3
4
while command
do
commands
done

while循环如同条件控制if一样是需要利用命令的退出状态码判断,当command执行退出状态码为0时,将继续执行循环,否则退出循环。commandif一样可以用test命令或者方括号等使用方法。例如:

1
2
3
4
5
6
7
8
var=2
while (( var-- > 0 ))
do
echo $var
done
# 将会输出:
# 1
# 0

until

until循环的基本语法是:

1
2
3
4
until command
do
command
done

until语法和while完全一样,但是规则确实相反的,until是直到command退出状态码为0的时候退出循环,而在非零的时候进入循环。例如:

1
2
3
4
5
6
7
8
9
var=0
until (( var++ > 2 ))
do
echo $var
done
# 将会输出:
# 1
# 2
# 3

break

break命令用于退出循环,即在循环中遇到break命令的时候将跳出,这一点和很多编程语言是一致的。而在Bash Shell中,可以指定break跳出那一层循环,格式为:

1
break n

其中n表示的就是跳出第几层循环,默认为1表示当前层,2表示当前层的外一层,以此类推。

continue

continue命令和break用法语法完全一致,不一样在于,循环中遇到continue不是退出循环,而是跳过continue命令直接进入下一次循环判断。同样的,可以后接一个参数指定跳出的是那一层循环。

其他几个用法

遍历目录中所有文件

例如:

1
2
3
4
5
6
7
8
for path in /home/ubuntu/* # 可以放多个目录,用空格分开
do
if [ -d $path ]; then
echo "$path is a directory"
else
echo "$path is a file"
fi
done

for的C-Style格式

for循环可以类似C语言的写法,格式为:

1
for (( variable assignment ; condition ; iteration process ))

这里有几项不遵循Bash Shellfor方法:

  • 变量的赋值可以包含空格;
  • 条件中的变量不以$做前缀;
  • 迭代处理不用使用expr命令格式。

例如:

1
2
3
4
for (( i=1; i <= 10; i++ ))
do
echo $i
done

可以使用多个变量:

1
2
3
4
for (( i=1, j=10 ; i <= 10; i++, j-- ))
do
echo "$i, $j"
done

处理循环的输出

循环的输出默认会输出到终端直接显示出来,我们可以将循环中的输出重定向到指定的文件中。做法就是在循环语句中的done后面加重定向操作。如下就可以把循环中所有的输出重定向到output.txt文件中了:

1
2
3
4
for (( i=1, j=10 ; i <= 10; i++, j-- ))
do
echo "$i, $j"
done > output.txt

while和until执行多条命令

whileuntil中的command处可以放置多条命令,但是最终结果有最后一条命令决定循环的执行。例如:

1
2
3
4
5
6
var=0
until echo "var=$var" # 或者用逗号(;)将多个命令分开,如下效果是一样的:
(( var++ > 2 )) # until echo "var=$var" (( var++ > 2 ))
do
echo $var
done
0%