【Linux】shell中的运行流程控制
目录
一.什么是运行流程控制
二.条件允许流程控制--if
2.1.单分支
2.2.双分支
2.3.多分支
if多分支练习
三.循环运行流程控制
无判定循环--for
判断循环--while,until
四.选择运行流程控制
五.自动应答--expect
5.1.固定位置的交互应答
5.2.非固定位置的交互应答
六.流程中断控制器
一.什么是运行流程控制
- 脚本默认的程序运行时自上而下
- 在生产环境,有的动作需要重复做,有的动作需要满足条件去做
- 如何按照我们需要的逻辑运行动作,这就是流程控制
二.条件允许流程控制--if
2.1.单分支
单分支脚本内容
#!/bin/bash
if [ "$*" = "hello" ]
thenecho linux
fi
脚本效果
2.2.双分支
双分支脚本内容
#!/bin/bash
id $1 &> /dev/null
if [ "$?" = "0" ]
thenecho $1 is exist
elseuseradd $1
fi
脚本效果
2.3.多分支
多分支脚本内容
#!/bin/bash
checkfile()
{
read -p "please input a checkfilename:" name
if [ -z "$name" ]
thenecho "Please input a checkfilename following $0!!"checkfile
elif [ ! -e "$name" ]
thenecho "$name is not exist"checkfile
elif [ -f "$name" ]
thenecho "$name is common file"checkfile
elif [ -d "$name" ]
thenecho "$name is directory"checkfile
fi
}
checkfile
脚本效果
if多分支练习
一个1分10秒倒计时的脚本
脚本测试
三.循环运行流程控制
无判定循环--for
#需求:批量创建用户,用户名以test开头,按数字序号变化;一共添加30个账号,密码为123456[root@localhost mnt]# vim test2.sh
#!/bin/bash
for ID in {1..30}
do[ "$ID" -lt "10" ] && {USERNAME="test0$ID"} || {USERNAME="test$ID"}id $USERNAME &> /dev/null && {echo $USERNAME is exist} || {useradd $USERNAMEecho 123456 | passwd --stdin $USERNAME &> /dev/null && {echo $USERNAME is created !!}}done
脚本代码
#通过把文件userlist中的内容提取出来作为用户名来创建用户
#!/bin/bash
if [ -z "$*" ]
thenecho "Error: Please input userlist file following $0 userlist"
elif [ ! -f "$*" ]
thenecho "$* is not exist"
elsefor name in $(cat $*);doid $name &> /dev/null && {echo "$name is exist"} || {useradd $nameecho "$name" | passwd --stdin $name &> /dev/null && {echo "$name is created !"}}done
fi
判断循环--while,until
while与until的区别就是
- while,当条件满足时反复执行指定动作,直到条件不满足时结束
- until,当条件不满足时反复执行指定动作,知道条件满足时结束
使用while判断循环来制作一个猜随机数的脚本
#!/bin/bash
LUCK(){ #生成随机数的函数,使用函数是为了方便调用
luck=$[$RANDOM%100]
}
TIMES(){ #记录猜错的次数的函数
guess_time=0
}
TIMES_WRONG(){ #设置猜错次数为三次,猜错三次后询问是否继续猜
((guess_time++))
[ "$guess_time" -eq "3" ] && {echo "you guess wrong $guess_time time,so you faild"read -p "Are you want play again (y/n)" WANT[ "$WANT" = "n" ] && {echo byeexit} || {LUCKTIMESecho $luck}
}
}
LUCK #生成随机数
TIMES #初始化次数
echo $luck #打印生成的随机数,方便实验
while true
doread -p "Please input a number between [0-99]: " INTif [ -z "$INT" ] #输入为空的情况thenecho "Error: you not input number,Please input a number between [0-99] "elif [ "$INT" = exit ] #输入为exit 即可退出thenecho byeexitelif [ "$INT" -lt "0" -o "$INT" -gt "99" ] #输入不在指定范围的情况thenecho "Error: you not input range number,Please input a number between [0-99] "elif [ "$INT" -eq "$luck" ] #猜中的情况thenecho "good,you guess it"read -p "are you want to continue guess ? (yes/no) " a #猜中后是否继续[ "$a" = "no" ] && {echo byeexit} || {LUCKTIMESecho $luck}elif [ "$INT" -lt "$luck" ] #输入小于随机数thenecho "you guess is too small"TIMES_WRONGelseecho "you guess is too big" #输入大于随机数TIMES_WRONGfi
done
脚本的执行测试
补充
四.选择运行流程控制
当脚本接收到操作者某个动作指令,脚本按照动作指令选择运行脚本中的某段代码,这就是选择流程控制
判断语句也可以达到选择流程控制的目的,但是其效率低下,因此我们在脚本中对于选择流程控制使用case来完成
使用case可以对于流程选择控制
#!/bin/bash
case $1 inhello|HELLO)echo linux;;linux|LINUX)echo hello;;*)echo error
esac
效果
示例
使用case选择控制流程来指定输入参数创建用户或删除用户
#!/bin/bash
[ "$#" -lt "2" ] && {echo "Please input action and userlist followding $0 !! "exit 1
}
for NAME in `cat $2`
docase $1 inadd|ADD|Add)id $NAME &> /dev/null && {echo "$NAME is exist !! "} || {useradd $NAMEecho " $NAME " | passwd --stdin $NAME &> /dev/null && {echo "$NAME is created ~"}};;del|DEL)id $NAME &> /dev/null && {userdel -r $NAME && {echo $NAME is deleted}} || {echo $NAME is not exist!!};;*)echo "Error: wrong action !! Please input add|del following $0 !!"esac
done
五.自动应答--expect
5.1.固定位置的交互应答
#使用多行重定向输入来作为交互脚本的参数
#!/bin/bash
sh /mnt/ask.sh <<EOF
fjw
21
linux
happy
EOF
5.2.非固定位置的交互应答
如果交互命令的问题位置不固定,那么我们需要用到expect来完成自动应答
使用expect需要安装expect
#使用expect可以回答非固定的交互脚本
[root@localhost mnt]# vim demo_answer.exp
[root@localhost mnt]# expect demo_answer.exp
spawn /mnt/ask.sh
What is your name?: fjw
Which subject you study?: linux
Are you happy?: happy
fjw is 's old study linux feel happy
[root@localhost mnt]#
由于交互文件注释了一个交互命令,所以没有识别到关键词就不会回答,就算交互文件的命令打乱expect也可以根据关键词精确回答问题
- set timeout x 设置问题等待超时
- spawn 监控交互命令脚本使expect可以读取问题
- send 发送问题答案,\r表示回车,exp_continue表示继续向下应答
- expect eof 表示在问题应答完毕后退出expect环境
- interact 表示在问题应答完毕后退出expect环境
- set 变量名 [lindex #arvg 0] 表示expect脚本后跟的第一串字符后面的1-3以此类推,0相当于sh脚本的$1,以此类推
应答语句中的变量
整合shell和expect到脚本中
六.流程中断控制器
测试脚本