系统相关
首页 > 系统相关> > Shell之函数及流程控制语序

Shell之函数及流程控制语序

作者:互联网

Shell之函数及流程控制语序

作用:
把一个复杂的语句块定义成一个字符串的方法
把一个脚本写成一个变量,用变量去调动程序

例如:
一个重复检测网络是否畅通的脚本:

#!/bin/bash
ping -c1 -w1 172.25.254.1
ping -c1 -w1 172.25.254.1
ping -c1 -w1 172.25.254.1
ping -c1 -w1 172.25.254.1
ping -c1 -w1 172.25.254.1

可以写成:

#!/bin/bash
PING()
{
ping -c1 -w1 172.25.254.1
}
PING
PING
PING
PING
PING

这么写的目的是为了减少脚本的空间大小,有效节约资源

循环函数脚本:

#!/bin/bash
ACTION()
{
read -p "Please input a word:" WORD
[ "$WORD" = "exit" ] && {
	exit 0
}
echo $WORD
ACTION
}
ACTION

for条件循环语句

for循环语句允许脚本一次性读取多个信息,然后逐一对信息进行操作处理,当要处理的数据有范围时,使用for循环语句再适合不过了。

循环语句格式:
for 循环条件
do 执行的动作
done 循环结束标志

循环条件:会依次执行满足的每一个条件,规定循环的次数。

应用示例:10秒倒计时脚本

#!/bin/bash
for num in {10..1}
do
        echo -n " $num "
        echo -ne  "\r"
        sleep 1
done

结束的三种方式:
exit :直接结束脚本运行
break:跳出所在的循环语句 继续进行脚本
continue:结束本次循环,进行下次循环

示例:
exit # 直接结束脚本的运行

#!/bin/bash
for num in {1..5}
do
	[ "$num" = '3' ] && exit    # exit
	echo $num
done
echo "hello welcome "

break # 结束循环 但是循环之后的语句还是要正常执行

#!/bin/bash
for num in {1..5}
do
	[ "$num" = '3' ] && break    
	echo $num
done
echo "hello welcome "

continue # 只是跳过num为3 那一次循环 继续进行下一次循环以及后续的语句

#!/bin/bash
for num in {1..5}
do
	[ "$num" = '3' ] && continue   #continue
	echo $num
done
echo "hello welcome "

if条件测试语句可以让脚本根据实际情况自动执行相应的命令。

if条件语句的单分支结构由if、then、fi关键词组成,而且只在条件成立后才执行预设的命令,相当于口语的“如果……那么……”。单分支的if语句属于最简单的一种条件判断结构

if条件测试语句格式:
if
then
elif
then
else
fi

示例:

[root@localhost mnt]# cat test.sh 
#!/bin/bash
A=$1
B=$2
if
	[ "$A" = "$B" ] 
then
	echo "yes"
fi
[root@localhost mnt]# sh test.sh 2 2    # 满足条件执行 
yes
[root@localhost mnt]# sh test.sh 2 3  # 不满足条件不执行

[root@localhost mnt]# cat test.sh 
#!/bin/bash
A=$1
B=$2
if
	[ "$A" = "$B" ] 
then
	echo "yes"
else
	echo "no"
fi
[root@localhost mnt]# sh test.sh 2  2
yes
[root@localhost mnt]# sh test.sh 2  1
no
[root@localhost mnt]# sh test.sh 2  3
no
[root@localhost mnt]# cat test.sh 
#!/bin/bash
A=$1
B=$2
if
	[ "$A" = "$B" ] 
then
	echo "等于"
elif
	[ "$A" -gt "$B" ]
then
	echo "大于"
else
	echo "小于"
fi
[root@localhost mnt]# sh test.sh 1 2
小于
[root@localhost mnt]# sh test.sh 1 1
等于
[root@localhost mnt]# sh test.sh 2 1 
大于

while条件循环语句是一种让脚本根据某些条件来重复执行命令的语句,它的循环结构往往在执行前并不确定最终执行的次数,完全不同于for循环语句中有目标、有范围的使用场景。while循环语句通过判断条件测试的真假来决定是否继续执行命令,若条件为真就继续执行

格式为:
while #条件
do # 动作
done #结束标志

示例:

[root@localhost mnt]# cat test.sh 
#!/bin/bash
i=0
while [ "$i" -ne "10" ]   # 进行循环的条件
do
	echo $i      # 执行的动作
	((i+=1))     # i 自加1
done
[root@localhost mnt]# sh test.sh  运行循环 直到条件不满足结束
0
1
2
3
4
5
6
7
8
9

until 循环执行一系列命令直至条件为 true 时停止。
until 循环与 while 循环在处理方式上刚好相反。
一般 while 循环优于 until 循环,极少数情况下,until 循环更加有用。

格式为:

until # 条件
do #动作
done #结束标志

示例:

[root@localhost mnt]# cat test.sh 
#!/bin/bash
i=15
until [ "$i" -lt "10" ]
do
	echo $i
	((i--))
done
[root@localhost mnt]# sh test.sh 
15
14
13
12
11
10

case语句是在多个范围内匹配数据,若匹配成功则执行相关命令并结束整个条件测试;而如果数据不在所列出的范围内,则会去执行星号(*)中所定义的默认命令。

case 语句在进行判断的时候是并发进行的,处理效率较高,if 语句在进行条件判断的时候是逐条从上往下,处理效率较低。

格式:

case  变量   in
			情况1)
			命令
			;;
			情况2)
			命令
			;;
			......
			*)   #剩余的所有情况
			命令
esac

示例:

#!/bin/bash
discrip()           # 定义函数
{
echo "action C|B|S|O "
read -p "please input the action following $0 :  " ACTION
case $ACTION in        # case 语句
        c|C)
        echo "$ACTION  is  create !!"
        ;;
        b|B)
        echo "$ACTION  is  backup !!"
        ;;
        S|s)
        echo "$ACTION  is  skip !!"
        ;;
        o|O)
        echo "$ACTION  is overwrite !!"
        ;;
        e|E)
        exit
        ;;
        *)
        echo "error : $ACTION is  unkown action !!"
esac
}

while true
do
        discrip    # while 语句调用函数
done

expect 相对于语句,更像是一条命令。
expect 是自动应答命令用于交互式命令的自动执行

spawn 是expect中的监控程序,其运行后会监控命令提出的交互问题
send 发送问题答案给交互命令
exp_continue 表示当问题不存在时继续回答下面的问题
expecte of 表示问题回答完毕退出expect环境
interact 表示问题回答完毕留在交互界面
set NAME [ lindex $argvn ] 定义变量
yum install expect.x86_64 -y # 安装软件 ,才能使用 expect

expect脚本一般以#!/usr/bin/expect 开头 规定其运行环境
spawn 新建一个进程,这个进程的交互由expect控制

示例:

1 存在一个交互式的脚本,

#!/bin/bash
read -p " who are you ? " NAME
read -p " where are you from ? " ADDR
read -p " how old are you ? " AGE
read -p " waht are you doing ? " ACTION

echo "$NAME is from $ADDR,now $AGE yeas old ,$ACTION  "

2 在运行该脚本的时候需要一步一步的输入所要的参数

[root@localhost mnt]# sh question.sh 
 who are you ? liu
 where are you from ? xi'an
 how old are you ? 18
 what are you doing ? study
liu is from xi'an,now 18 yeas old ,study  

3 使用expect 可以一次回答所有的问题。

vim anwser.exp      # 注意文件后缀 便于区分
#!/usr/bin/expect     # 注意规定运行环境
set NAME [ lindex $argv 0 ]
set ADDR [ lindex $argv 1 ]
set AGE [ lindex $argv 2 ]
set ACTION [ lindex $argv 3 ]     # 定义四个变量
spawn /mnt/question.sh    # 监控需要进行交互式的脚本
expect {
        "who"   { send "$NAME\r";exp_continue }
        "where" { send "$ADDR\r";exp_continue }    exp_continue 表示当问题不存在时继续回答下面的问题
        "how"   { send "$AGE\r";exp_continue }
        "what"  { send "$ACTION\r" }   # 根据问题发送答案
}
expect eof    expect eof   表示问题回答完毕退出expect环境

4 执行

chmod 777 /mnt/question.sh # 被检控的文件必须有可执行权限

[root@localhost mnt]# expect anwser.exp shang xian  18  study # 运行expect  后面跟这问题的答案
spawn /mnt/question.sh
 who are you ? liu
 where are you from ? xian
 how old are you ? 18
 what are you doing ? study
liu is from xian , now 18 yeas old,  study !!   # 一次回答所有的问题并输出结果!

5 也可以将 anwser.exp 修改成可以运行在shell 脚本中

修改后的内容

#!/bin/bash
/usr/bin/expect <<EOF
spawn /mnt/question.sh
expect {
"who"   { send "$1\r";exp_continue }
"where" { send "$2\r";exp_continue }
"how"   { send "$3\r";exp_continue }
"what"  { send "$4\r" }
}
expect eof
EOF

执行结果

[root@localhost mnt]# sh anwser.sh shang 18 xian study
spawn /mnt/question.sh
 who are you ? liu
 where are you from ? 18
 how old are you ? xian
 what are you doing ? study
liu is from 18 , now xian yeas old,  study !!

END

标签:语句,bin,Shell,语序,mnt,echo,sh,expect,流程
来源: https://blog.csdn.net/weixin_44828950/article/details/90382675