Shell 脚本的循环控制(for

熟悉其他高级语言的伙伴们肯定了解循环控制语法是编程中非常基础的内容,今天就介绍Shell 中设计循环控制的语法,for/while/until 等内容。

for 命令

for 命令是最简单的循环控制语句,它的格式为:

for var in list
do
commands
done

语法比较简单,不做冗余的介绍了,直接上例子:

Shell 脚本的循环控制(for/while/until)

图1

输出结果:
The next brand is MacOS
The next brand is Windows
The next brand is Linux
The next brand is Unix
The next brand is Deepin
The last brand is Deepin
The modified brand is Deepin

从图1 中;item 作为临时变量在 ”MacOS WIndows Linux Unix Deepin"列表中循环赋值,然后循环执行do 至 done 之间的语句。这里值得注意的是:item 作为 for 循环的局部变量(或者是栈变量)在循环体外依然可以访问,例如在done 退出循环体后,依然可以访问 item 这个for循环体内的局部变量,这个是和其他高级语言不太相同的。具有高级语言的伙伴们可能第一次会觉得有些奇怪,不过这是Shell 语言的特点,这和C++那些声明式的高级语言是有区别的。在C++中所有变量使用前必须要声明类型,而在Shell 中却没有这样的规定。for 循环中的列表可以有多种形式,可以像图1中那样直接枚举,也可以定义成一个变量,也可以通过命令的返回作为 list 对象(例如可以通过cat file将file中的内容作为list返回)这里就不一一举例了。

修改字段分隔符

上面的例子中,我们发现,list使用过空格来作为分隔符的。那么是什么决定用空格作为list分隔符的呢。其实这里是通过环境变量 IFS (internal field separator) bash shell 的分隔符默为:

  • 空格
  • 制表符
  • 换行符

默认的分隔符优惠会造成麻烦,尤其是需要处理的数据中包含空格时。例如

Shell 脚本的循环控制(for/while/until)

文件名为:my_file

如图,第二行"New York"中包含了空格,所以for 循环式,“New York”会被认为两个元素。此结果并不是我们想要的。这是我们可以修改 IFS 只为换行符,来规避这种情况。

IFS=$'\n':; #可以一次指定多个符号作为分隔符,只需要将符号串联一起。此例子中换行符,冒号和分号都作为分隔符。
Shell 脚本的循环控制(for/while/until)

图2

输出结果:
value is China
value is New York
value is London
value is Japan

图2中,我们修改IFS前先将旧的IFS保存下来,然后在适当的地方恢复,这对于脚本中部分逻辑需要恢复默认的 IFS 时提供了方法。

while 命令

while 命令其实是 if-then 和 for 循环的结合体。格式如下:

while test command
do
commands
done

当 "test command" 返回码为 0 时,do 后的commands 会循环执行。此处应该注意的是:"test command" 需要在 do 的执行过程中发生变化,否则while循环将会无法停止。

until 命令

until 命令和 while 命令工作方式完全相反,until 是等到命令的返回码不为0 时,才执行循环体中的命令,格式如下:

until test commands
do
other commands
done

上例子:

Shell 脚本的循环控制(for/while/until)

图3

图3中 until 后判断var1 是否为0, 不为零是, 表达式返回码为非 0 ,此时执行do 循环体内的命令,当 var1 为0 时, 返回码为0, 此时until 循环结束。

循环控制

break 命令:是退出当前循环的简单命令。

Shell 脚本的循环控制(for/while/until)

图4

输出结果
the number is 1
the number is 2
the number is 3
The loop is completed

从图4中可以看出,当 var==4 时,for 循环会满足break 条件而退出。break 也适合while 和 until 的循环。break 的默认规则和其他语言,例如C/C++相同,只会退出当前的循环,如果出现循环嵌套,那么只会退出break 所在的循环。

break 跳出外部循环

break 语句除了默认的跳出当前循环,还能控制跳出外部循环,这是C/C++语言没有的特性。语法格式为:

break n #n为1则是跳出当前循环,n为2 则是跳出上一级循环

上例子:

Shell 脚本的循环控制(for/while/until)

图5

输出结果:

Outer loop: 1
Inner loop:1

Inner loop:2
Inner loop:3
Inner loop:4

从图5中可以看出是一个嵌套循环,在内部循环中,当b大于4时,"break 2" 会跳出上一级循环,所以外部循环只执行一次就被内部循环的break 语句退出了。这种用法在其他语言中不太常见,而且也不是特别推荐的用法。因为推出外部循环处理不当,可能会产生异非想要的结果。

continue 命令

continue 的原理和C/C++相同,会提前终止循环,但是不会退出循环。对于没有编程经验的小伙伴,听起来有点绕,可以理解为程序逻辑的短路行为。直接上代码:

Shell 脚本的循环控制(for/while/until)

图6

输出结果为:
the number is 1
the number is 2
the number is 3
the number is 4
the number is 5
the number is 10
the number is 11
the number is 12
the number is 13
the number is 14

如图6, continue 命令会跳过 5<var1>

continue 短路外部循环

continue 也有 break 类似的控制外部循环的命令,语法格式为:

continue n #短路到外部n层嵌套循环

例子和 ‘break n’类似,这里就不再赘述了。

循环语句在实际工作中是非常有用的,例如你想创建多个用户,那么就可以在所有用户名存储在文件中,然后写个shell脚本去读取文件,然后通过循环操作依次去除用户名,然后再通过 useradd 命令添加用户。所有命令在 shell脚本中执行,一气呵成,非常便利。

/<var1>


分享到:


相關文章: