目录
问:什么是shell脚本语言的流程控制?
答:流程控制是改变程序运行顺序的指令。
1、if 语句
if语句就是进行一个if判断,判断结果为真是将怎么样处理,为假时需要怎么样处理的一个语句,if语句分为单分支、双分支和多分支,简单的理解就是一层if判断单层命令,一层if判断两次命令和多层if判断。
格式:
if list; then list; [ elif list; then list; ] ... [ else list; ] fi
1. if语句单分支
就是只有一个if判断的shell脚本,这主要就是做为真的判断,就是为真才执行后面的命令,是否是直接退出的,这个很少场景使用的。
格式:
if 条件表达式; then
命令
fi
或是
if 条件表达式
then
命令
fi
示例:
#!/bin/bash
N=10
if [ $N -gt 5 ]; then
echo yes
fi
或者
#!/bin/bash
N=10
if [ $N -gt 5 ]
then
echo yes
fi
执行结果:
# sh test.sh
yes
2. if语句双分支
说叫双分支其实跟单分支类似也是只有一个if判断的shell脚本,但是区别在于为真的判断,就是为真执行第一个命令,为假是执行第二个命令的,这个使用的场景很多。
格式:
if 条件表达式; then
命令
else
命令
fi
或者
if 条件表达式
then
命令
else
命令
fi
示例:
#!/bin/bash
N=10
if [ $N -lt 5 ]; then
echo yes
else
echo no
fi
或者
N=10
if [ $N -lt 5 ]
then
echo yes
else
echo no
fi
执行效果:
# bash test.sh
no
示例2:
#判断 crond (定时任务)进程是否运行
#!/bin/bash
NAME=crond
NUM=$(ps -ef |grep $NAME |grep -vc grep)
if [ $NUM -eq 1 ]; then
echo "$NAME running."
else
echo "$NAME is not running!"
fi
或者
NAME=crond
NUM=$(ps -ef |grep $NAME |grep -vc grep)
if [ $NUM -eq 1 ]
then
echo "$NAME running."
else
echo "$NAME is not running!"
fi
执行效果:
# sh test.sh
crond running.
crond进行都是开机自起的,一般不错特殊操作,基本都是运行的状态的。
示例3:
#检查主机是否存活
#!/bin/bash
if ping -c 1 192.168.1.1 >/dev/null; then
echo "OK."
else
echo "NO!"
fi
或者
if ping -c 1 192.168.1.1 >/dev/null
then
echo "OK."
else
echo "NO!"
fi
执行效果:
# sh test.sh
NO!
if 语句可以直接对命令状态进行判断,就省去了获取$?这一步,但是可以利用这个$?
if [ $? -eq 0 ] then echo no else echo yes fi
3. if语句多分支
if语句的多分支就是多层if的判断,主要是使用在当不确定条件符合哪一个时,就可以把已知条件判断写出来,做相应的处理的场景。
格式:
if 条件表达式; then
命令
elif 条件表达式; then
命令
else
命令
fi
或者
if 条件表达式
then
命令
elif 条件表达式
then
命令
else
命令
fi
示例1:
#!/bin/bash
N=$1
if [ $N -eq 3 ]; then
echo "eq 3"
elif [ $N -eq 5 ]; then
echo "eq 5"
elif [ $N -eq 8 ]; then
echo "eq 8"
else
echo "no"
fi
或者
N=$1
if [ $N -eq 3 ]
then
echo "eq 3"
elif [ $N -eq 5 ]
then
echo "eq 5"
elif [ $N -eq 8 ]
then
echo "eq 8"
else
echo "no"
fi
执行效果:
# sh test.sh 9
no
# sh test.sh 6
no
# sh test.sh 5
eq 5
示例2:
#判断一个学生的优秀,良、及格和不及格先,并显示分数
#!/bin/bash
num=$1
if [ $num -gt 95 ]
then
echo "this is student excellent,this is $num"
elif [ $num -gt 80 ]
then
echo "this is student good,this is $num"
elif [ $num -gt 60 ]
then
echo "this is student pass,this is $num"
else
echo "this is student fail,this is $num"
fi
执行效果:
# sh test.sh 98
this is student excellent,this is 98
# sh test.sh 84
this is student good,this is 84
# sh test.sh 67
this is student pass,this is 67
# sh test.sh 57
this is student fail,this is 57
2、for语句
for语句,也叫判断语句,但是用的最多场景是for循环场景的,for语句也是为真进行处理的。
格式:
for name [ [ in [ word ... ] ] ; ] do list ; don
for 变量名 in 取值列表; do
命令
done
或者
for 变量名 in 取值列表
do
命令
done
示例:
#!/bin/bash
for i in {1..3}; do
echo $i
done
或者
#!/bin/bash
for i in "$@"; {
echo $i
}
执行效果:
# sh test.sh
1
2
3
# sh test.sh 1 2 3
1
2
3
示例2:
for 循环的取值列表是以空白符分隔,也就是shell系统变量里的$IFS:
#!/bin/bash
for i in 12 34; do
echo $i
done
或者
for i in 12 34
do
echo $i
done
执行效果:
# sh test.sh
12
34
分隔符也是可以自定义指定的,可以重新赋值$IFS 变量:
#!/bin/bash
OLD_IFS=$IFS
IFS=":"
for i in $(head -1 /etc/passwd); do
echo $i
done
执行效果:
# sh test.sh
root
x
0
0
root
/root
/bin/bash
执行这个IFS=$OLD_IFS 可以恢复默认值
示例3:
for 循环还有一种 C 语言风格的语法,常用于计数、打印数字序列 等场景
格式:
for (( expr1 ; expr2 ; expr3 )) ; do list ; done
示例4:
答应1-5的数字
#!/bin/bash
for ((i=1;i<=5;i++)); do
echo $i
done
执行效果:
# sh test.sh
1
2
3
4
5
示例5:
利用for和if语句进行一个IP地址的是否可以ping通
#!/bin/bash
for ip in 192.168.1.{1..254}
do
if ping -c 1 $ip >/dev/null
then
echo "$ip OK."
else
echo "$ip NO!"
fi
done
执行效果:
# sh test.sh
192.168.1.1 NO!
192.168.1.2 NO!
192.168.1.3 NO!
192.168.1.4 NO!
192.168.1.5 NO!
.......
192.168.1.254 NO!
3、while 语句
while语句和for语句是类似的,一般都是使用在循环的场景中,当条件表达式为 false 时,终止循环,为真则将继续循环
格式:
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
示例2:
while在使用的时候,有会有存在一直都是true的情况,那么程序就会进入到死循环,一旦这样的情况,切记不要轻易执行。
1、可以条件表达式直接用 true
2、还可以条件表达式用冒号,冒号在 Shell 中的意思是不做任何操作。但状态是 0,因此为 true:
#!/bin/bash
while [ 1 -eq 1 ]; do
echo "yes"
done
或者
while true; do
echo "yes"
done
或者
while :; do
echo "yes"
done
示例 3:
利用while语句来逐行处理文本
需要处理的文本
# cat a.txt
a b c
1 2 3
x y z
注:与 while 关联的还有一个 until 语句,它与 while 不同之处在于,是当条件表达式为 false 时才循 环,实际使用中比较少。
4、循环until语句
until语句是当条件表达式为 false 时才循 环,为真时则退出的流程语句,在现实实际使用场景中比较少,但是一些特殊的场景会使用到的。
示例:
[root@~ test]# cat test.sh
#!/bin/bash
i=1
until [ $i -gt 10 ]
do
echo "$i"
let i++
done
执行效果:
[root@~ test]# sh test.sh
1
2
3
4
5
6
7
8
9
10
执行的效果可以看出来,如果条件的结果是false时则会进行到后续命令的执行,如果是true的则直接退出来循环的执行。
5、循环控制语句,break 和 continue
break 的作用是终止循环,就是直接跳出了所有的循环。
continue 是跳出当前循环,但是会进入下一次的循环的
示例1:
[root@~ test]# cat test.sh
#!/bin/bash
N=0
while true
do
let N++
if [ $N -eq 5 ]
then
break
fi
echo $N
done
执行效果:
[root@~ test]# sh test.sh
1
2
3
4
里面用了 if 判断,并用了 break 语句,它是跳出循环。与其关联的还有一个 continue 语句,它是 跳出本次循环。
示例2:
[root@~ test]# cat test.sh
#!/bin/bash
N=0
while [ $N -lt 5 ]
do
let N++
if [ $N -eq 3 ]
then
continue
fi
echo $N
done
执行效果:
[root@~ test]# sh test.sh
1
2
4
5
当变量 N 等于 3 时,continue 跳过了当前循环,没有执行下面的 echo
注意:continue 与 break 语句只能循环语句中使用 ,比如for、while 、until语句中出现的。
6、模式匹配case 语句
case 语句一般用于选择性来执行对应部分块命令。
格式:
case 模式名 in 模式 1) 命令 ;; 模式 2) 命令 ;; *) 不符合以上模式执行的命令 esa
注:每个模式必须以右括号结束,命令结尾以双分号结束 。
示例1:
#!/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 下有一部分服务启动脚本都是这么写的。
模式也支持正则,匹配哪个模式就执行那个:
示例2:
#!/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
7、select 语句
select 是一个类似于 for 循环的语句。 格式:select name [ in word ] ; do list ; done
select 变量 in 选项 1 选项 2
do
break
done
示例1:
#!/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
示例2:
上面的select语句作为菜单用的话,循环第二次后就不再显示菜单 了,在某些场景并不适用的。 在外面加个死循环,每次执行一次 select 就 break 一次,这样就能每次显示菜单了:
#!/bin/bash
while true
do
select mysql_version in 5.1 5.6
do
echo $mysql_version
break
done
done
执行效果:
[root@~ test]# sh test.sh
1) 5.1
2) 5.6
#? 1
5.1
1) 5.1
2) 5.6
加入循环之后并每次break之后,就是输入一个选项之后会重现弹出菜单选择列表出来。
示例3:
还能再次优化一下:如果再判断对用户输入的编号执行相应的命令,如果用 if 语句多分支的话要复杂许多,用 case 语 句就简单多了。
[root@~ test]# cat test.sh
#!/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
执行效果:
[root@~ test]# sh 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:
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
这里有提示输入的参数,这样在某些场景是提高用户的使用好感率。
总结:
本篇就介绍了shell脚本语言中常见使用到流程控制语句,if...else...fi的判断,for、while、until的循环。case...;;....;;...esac的模式匹配。
希望给大家提供帮助,支持博主记得点赞加关注!!!