Shell流程控制

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Shell流程控制相关的知识,希望对你有一定的参考价值。

防伪码:床前明月光,疑是地上霜。

流程控制是改变程序运行顺序的指令。

f 4.1 if  语句

格式:if list; then list; [ elif list; then list; ] ... [ else list; ] fi

4.1.1 单分支

if 条件表达式; then

命令

fi

示例:

#!/bin/bash

N=10

if [ $N -gt 5 ]; then

echo yes

fi

# bash test.sh

yes

技术分享

4.1.2 双分支

if 条件表达式; then

命令

else

命令

fi

示例:

#!/bin/bash

N=10

if [ $N -lt 5 ]; then

echo yes

else

echo no

fi

# bash test.sh

no

技术分享

4.1.3 多分支

if 条件表达式; then

命令

elif 条件表达式; then

命令

else

命令

fi

示例:

#!/bin/bash

N=10

if [ $N -gt 5 ]; then

echo "gt 5"

elif [ $N -gt 6 ]; then

echo "gt 6"

else

echo no

fi

如果第一个条件符合就不再向下匹配。

技术分享

r 4.2 for  语句

格式:for name [ [ in [ word ... ] ] ; ] do list ; done

for 变量名 in 取值列表; do

命令

done

示例:

#!/bin/bash

for i in {1..3}; do

echo $i

done

# bash test.sh

1

2

3

技术分享

默认 for 循环的取值列表是以空白符分隔,也就是第一章讲系统变量里的$IFS:

#!/bin/bash

for i in 12 34; do

echo $i

done

# bash test.sh

12

34

技术分享

如果想指定分隔符,可以重新赋值$IFS 变量:

#!/bin/bash

OLD_IFS=$IFS

IFS=":"

STR="12:34:45"

for i in $STR; do

echo $i

done

IFS=$OLD_IFS # 恢复默认值

# bash a.sh

12

34

45

技术分享

for 循环还有一种 C 语言风格的语法,常用于计数、打印数字序列:

for (( expr1 ; expr2 ; expr3 )) ; do list ; done

#!/bin/bash

for ((i=1;i<=5;i++)); do # 也可以 i--

echo $i

done

技术分享

 4.3 while  语句

格式:while list; do list; done

while 条件表达式; do

命令

done

示例 1:

#!/bin/bash

N=0

while [ $N -lt 5 ]; do

let N++

echo $N

done

# bash test.sh

1

2

3

4

5

技术分享

当条件表达式为 true 时,终止循环。

示例 2:条件表达式为 true,将会产生死循环

#!/bin/bash

while [ 1 -eq 1 ]; do

echo "yes"

done

技术分享

也可以条件表达式直接用 true:

#!/bin/bash

while true; do

echo "yes"

done

技术分享

还可以条件表达式用冒号,冒号在 Shell 中的意思是不做任何操作。但状态是 0,因此为 true:

#!/bin/bash

while :; do

echo "yes"

done

技术分享

示例 3:逐行处理文本

文本内容:

# cat a.txt

a b c

1 2 3

x y z

要想使用 while 循环逐行读取 a.txt 文件,有三种方式:

方式 1:

#!/bin/bash

cat ./a.txt | while read LINE; do

echo $LINE

done

技术分享

方式 2:

#!/bin/bash

while read LINE; do

echo $LINE

done < ./a.txt

技术分享

方式 3:

#!/bin/bash

exec < ./a.txt # 读取文件作为标准输出

while read LINE; do

echo $LINE

done

技术分享

与 while 关联的还有一个 until 语句,它与 while 不同之处在于,是当条件表达式为 false 时才循

环,实际使用中比较少,这里不再讲解。

4.4 k break 和 和 e continue  语句

break 是终止循环。

continue 是跳出当前循环。

示例 1:在死循环中,满足条件终止循环

#!/bin/bash

N=0

while true; do

let N++

if [ $N -eq 5 ]; then

break

fi

echo $N

done

# bash test.sh

1

2

3

4

技术分享

里面用了 if 判断,并用了 break 语句,它是跳出循环。与其关联的还有一个 continue 语句,它是

跳出本次循环。

示例 2:举例子说明 continue 用法

#!/bin/bash

N=0

while [ $N -lt 5 ]; do

let N++

if [ $N -eq 3 ]; then

continue

fi

echo $N

done

# bash test.sh

1

2

4

5

技术分享

当变量 N 等于 3 时,continue 跳过了当前循环,没有执行下面的 echo。

注意:e continue 与 与 k break  语句只能循环语句中使用。

4.5 5 e case  语句

case 语句一般用于选择性来执行对应部分块命令。

格式:case word in [ [(] pattern [ | pattern ] ... ) list ;; ] ... esac

case 模式名 in

模式 1)

命令

;;

模式 2)

命令

;;

*)

不符合以上模式执行的命令

esac

每个模式必须以右括号结束,命令结尾以双分号结束。

示例:根据位置参数匹配不同的模式

#!/bin/bash

case $1 in

start)

echo "start."

;;

stop)

echo "stop."

;;

restart)

echo "restart."

;;

*)

echo "Usage: $0 {start|stop|restart}"

esac

# bash test.sh

Usage: test.sh {start|stop|restart}

# bash test.sh start

start.

# bash test.sh stop

stop.

# bash test.sh restart

restart.

技术分享

技术分享

上面例子是不是有点眼熟,在 Linux 下有一部分服务启动脚本都是这么写的。

模式也支持正则,匹配哪个模式就执行那个:

#!/bin/bash

case $1 in

[0-9])

echo "match number."

;;

[a-z])

echo "match letter."

;;

‘-h‘|‘--help‘)

echo "help"

*)

echo "Input error!"

exit

esac

# bash test.sh 1

match number.

# bash test.sh a

match letter.

# bash test.sh -h

help

# bash test.sh --help

help

模式支持的正则有:*、?、[ ]、[.-.]、|。后面有章节单独讲解 Shell 正则表达式。

4.6 6 t select  语句

select 是一个类似于 for 循环的语句。

格式:select name [ in word ] ; do list ; done

select 变量 in 选项 1 选项 2; do

break

done

示例:

#!/bin/bash

select mysql_version in 5.1 5.6; do

echo $mysql_version

done

# bash test.sh

1) 5.1

2) 5.6

#? 1

5.1

#? 2

5.6

技术分享

用户输入编号会直接赋值给变量 mysql_version。作为菜单用的话,循环第二次后就不再显示菜单

了,并不能满足需求。

在外面加个死循环,每次执行一次 select 就 break 一次,这样就能每次显示菜单了:

#!/bin/bash

while true; do

select mysql_version in 5.1 5.6; do

echo $mysql_version

break

done

done

# bash test.sh

1) 5.1

2) 5.6

#? 1

5.1

1) 5.1

2) 5.6

#? 2

5.6

1) 5.1

2) 5.6

技术分享

如果再判断对用户输入的编号执行相应的命令,如果用 if 语句多分支的话要复杂许多,用 case 语

句就简单多了。

#!/bin/bash

PS3="Select a number: "

while true; do

select mysql_version in 5.1 5.6 quit; do

case $mysql_version in

5.1)

echo "mysql 5.1"

break

;;

5.6)

echo "mysql 5.6"

break

;;

quit)

exit

;;

*)

echo "Input error, Please enter again!"

break

esac

done

done

# bash test.sh

1) 5.1

2) 5.6

3) quit

Select a number: 1

mysql 5.1

1) 5.1

2) 5.6

3) quit

Select a number: 2

mysql 5.6

1) 5.1

2) 5.6

3) quit

Select a number: 3

技术分享

如果不想用默认的提示符,可以通过重新赋值变量 PS3 来自定义。这下就比较完美了!

谢谢观看,真心的希望能帮到您!

本文出自 “一盏烛光” 博客,谢绝转载!

以上是关于Shell流程控制的主要内容,如果未能解决你的问题,请参考以下文章

Shell 流程控制

shell--8Shell 流程控制

shell流程控制

Shell编程 流程控制——流程控制语句

Shell 学习--流程控制

Shell 流程控制