shell的编程结构体(函数、条件结构、循环结构)(4)

[root@linuxidc ~]# let i=1,sum=0;while [ $i -le 10 ];do let sum=sum+i;let ++i;done;echo $sum 55

在此例中,test_cmd_list中只有一个命令[ $i -le 10 ],所以它的状态直接决定整个循环何时退出。

test_cmd_list中可以是多个命令,但千万要考虑清楚,是否要让决定退出循环的测试命令处在列表的尾部,否则将进入无线循环。

[root@linuxidc ~]# let i=1,sum=0;while echo $i;[ $i -le 10 ];do let sum=sum+i;let ++i;done;echo $sum 1 2 3 4 5 6 7 8 9 10 11 55

对于while循环,有另外两种常见的写法:

(1).test_cmd_list部分使用一个冒号":"或者true命令,使得while进入无限循环。

while :;do        # 或者"while true;do"

...

done

(2).使用read命令从标准输入中按行读取值,然后保存到变量line中(既然是read命令,所以可以保存到多个变量中),读取一行是一个循环。

由于标准输入既可以来源于重定向,也可以来源于管道(本质还是重定向),所以有几种常见的写法:

写法一:使用管道传递内容,这是最烂的写法

echo "abc xyz" | while read field1 field2    # 按IFS分割,并赋给两个变量

do 

    ...

done

写法二:

while read line

do

    ...

done <<< "abc xyz"

写法三:从文件中读取内容

while read line

do

    ...

done </path/filename

既然是读取标准输入,于是还可以衍生出几种写法:

方法四:while read var;do ...;done < <(cmd_list)          # 采用进程替换

方法五:exec <filename;while read var;do ...;done         # 改变标准输入

尽管写法有多种,但注意,它们并不等价。方法一中使用的是管道符号,这使得while语句在子shell中执行,这意味着while语句内部设置的变量、数组、函数等在循环外部都不再生效例如:

#!/bin/bash echo "abc xyz" | while read line do new_var=$line done echo the variable new_var is null: $new_var?

该脚本的执行结果中,$new_var的值将为空。

使用除写法一外的任意一种写法,在while循环外部都能继续获得while内的环境。例如,使用写法二的here string代替写法一:

#!/bin/bash while read line do new_var=$line done <<< "abc xyz" echo the variable new_var is null: $new_var?

由此可以发现,在上面的5种写法中,大众使用的最广泛写法一其实是最烂的一种,如果没注意写法一中while是在子shell运行,很可能会一直疑惑,为什么在while循环里设置好的变量或数组在循环一结束就成了空值呢。

1.7 循环结构:until

until和while循环基本一致,所不同的仅仅只是test_cmd_list的意义。

语法结构:

until test_cmd_list; do cmd_list; done

首先判断test_cmd_list中的最后一个命令,如果状态码为非0,则执行一次cmd_list,然后再返回循环的开头再次执行test_cmd_list,直到test_cmd_list的最后一个命令状态码为0时,才退出循环。

和while不同的是,当判断test_cmd_list最后一个命令的状态满足退出条件时直接退出循环,也就是说循环是在test_cmd_list最后一个命令处退出的。

例如:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/13530.html