shell中循环语句、条件语句和自动应答语句的控制

shell中循环语句、条件语句和自动应答语句的控制

1、for循环语句

for语句的结构为:
for 定义变量
do 使用变量,执行动作
done 结束标志

脚本练习1:check_host.sh,用此脚本检测 10 台与您当前主机直连主机是否网络通常,如果网络通常请显示主机的 ip 列表
脚本如下,第一个使用的for循环是1到10一个一个列出的做法;也可以使用1..10的方法来表示1到10的连续数字;还可以使用seq的方式,也是表示1到10的连续数字,他还可以指定步长,比如seq 1 2 10,就等价于1,3,5,7,9
shell中循环语句、条件语句和自动应答语句的控制
shell中循环语句、条件语句和自动应答语句的控制
shell中循环语句、条件语句和自动应答语句的控制
shell中循环语句、条件语句和自动应答语句的控制

脚本练习2:create_user.sh,已有一个文件userlist,里面有三个用户名,执行脚本时建立这三个用户,并提示成功建立
脚本如下,值的注意的是不能只局限于问题的表面,要看深层次,比如创建用户必须是root用户,要先判定是否为root用户,还有不输入userlist要报错,userlist文件如果不存在也要报错。
shell中循环语句、条件语句和自动应答语句的控制
效果如下
shell中循环语句、条件语句和自动应答语句的控制

脚本练习3:在脚本2的基础上,还多加入了密码文件passlist,里面有三个密码,分别对应上面的三个用户,分别改密码,并提示成功。
脚本如下,先要判断userlist和passlist两个文件的行数是否一致,如果不一致报错退出。然后一行一行的抓取名字和密码,并修改。
shell中循环语句、条件语句和自动应答语句的控制
效果如下
shell中循环语句、条件语句和自动应答语句的控制

2、while条件语句

判断一次,条件为真执行动作,格式为whlie。。。do。。。done

练习:之前使用函数实现的循环交互式传参,用while实现
脚本如下,这里true表示条件始终成立,所以一直循环。
shell中循环语句、条件语句和自动应答语句的控制

3、until条件语句

判断一次,条件为假执行动作,格式为until。。。do。。。done

练习:之前使用while实现的循环交互式传参,用until实现
脚本如下,这里false表示条件始终成立,所以一直循环。
shell中循环语句、条件语句和自动应答语句的控制

4、if条件语句

多次判断,格式为 if…then…elif…then…else…fi
练习如下:输入5显示five,输入4显示four,输入其他的显示error
shell中循环语句、条件语句和自动应答语句的控制

脚本练习1:创建一个十以内的随机值,去猜测,猜测正确显示恭喜,猜测错误显示失败,一直猜才中为止
脚本如下,
shell中循环语句、条件语句和自动应答语句的控制
脚本练习2:在脚本1的基础上,猜测错误后,提示是猜大了还是猜小了
脚本如下,多加一层判定,输入exit就离开。相等就输出对,不相等判定是大了还是小了。
shell中循环语句、条件语句和自动应答语句的控制

5、case语句

if语句判定时,是从上到下判定的,假如判定有很多,恰好最后一个才符合条件,那么效率就比别人慢,这样很不合适。现在需要点名机制,case语句是效率一样。

脚本练习:ctrl_user.sh,要求如下:
(1)、询问指令,如果输入create或c,询问名字,输入westos,如果westos存在,提示用户已存在,再次询问用户名字;如果westos不存在,询问密码(无回显),创建用户并修改密码,提示创建成功,然后返回询问指令,直到输入exit脚本退出。
(2)、询问指令,如果输入delete或d,询问名字,输入westos,如果westos存在,显示westos存在,然后删除该用户并显示成功删除,返回询问指令;如果westos不存在,显示westos不存在,再次询问名字,如果输入的是exit,返回询问指令
脚本如下,
shell中循环语句、条件语句和自动应答语句的控制
效果如下
shell中循环语句、条件语句和自动应答语句的控制

6、终止语句

continue 终止当前循环提前进入下个循环
break 终止当前所在语句所有动作,打破循环,进行语句外的其他动作
exit 脚本退出

7、expect应答语句

我们写脚本的目的就是为了自动执行,但是有些命令需要输入参数才可以执行,比如ssh远程连接时,会要求输入密码,输入成功才可以执行后面的操作,有时还需要先输入yes认证完再输入密码,那这种情况怎么办呢?就需要用到expect应答脚本。
为了模拟上面遇到的问题,现在设置一个提问脚本,并给执行权限
shell中循环语句、条件语句和自动应答语句的控制

执行该提问脚本时,需要一个一个输入答案;我们也可以利用之前学过的多行输入EOF,提前把答案写入。但是如果某个问题可能出现也可能不出现时(比如ssh的认证yes),这种EOF的方式很可能全部串行。所以我们需要expect根据问题问什么来进行回答。
shell中循环语句、条件语句和自动应答语句的控制
首先安装expect软件。expect用的不是shell,它有自己独立的环境。现在创建回答脚本answer.exp,第一行是expect的运行环境,第二行是监控(执行)问题的那个文件,最后一行表示退出expect环境。中间的就是看到什么关键词时,怎么回答问题,注意\r一定要写,表示回车的意思,不然会一直卡住不动
shell中循环语句、条件语句和自动应答语句的控制

如果现在其中一个问题注释掉,测试是否会发生错乱呢?如下图,还是错乱了,卡住了,为什么呢?因为我们用了多个expect回答问题,每个人管每个人的,有一个人找不到问题就捣乱,所以我们应该让一个人回答多个问题。
shell中循环语句、条件语句和自动应答语句的控制

改进如下,注意回答完后面要加exp_continue,因为expect没结束,后面还要回答呢,最后一个就不用加exp_continue了。
shell中循环语句、条件语句和自动应答语句的控制

效果如下,即使少了个问题,回答也没有错乱
shell中循环语句、条件语句和自动应答语句的控制

以上的回答方式,答案是固定的,如果我们不想固定呢?脚本修改如下,第二行的意思是如果找不到答案等待一秒退出。第三行意思是脚本后跟的第一串字符赋给NAME变量,第四五六行同理,回答时就可以按照脚本后所跟的答案来回答。
shell中循环语句、条件语句和自动应答语句的控制
效果如下,
shell中循环语句、条件语句和自动应答语句的控制

以上是expect的基本用法,必须在他自己的环境中才能运行。如果脚本的第一行改为#!/bin/bash再执行脚本就报错了,如下图
shell中循环语句、条件语句和自动应答语句的控制
但是我们是想让expect回答bash中的问题,怎么融合呢?脚本改进如下,执行现在的脚本效果和前面一致。
shell中循环语句、条件语句和自动应答语句的控制
脚本练习:host_list.sh,要求如下
检测 172.25.254.1-172.25.254.10 网络是否开启,如果网络正常请生成解析列表 hosts_list,格式如下ip 主机名称。例如: 172.25.254.1 为开启状态主机名为 westos_student1.westos.org,hosts_list 中出现172.25.254.1 westos_student1.westos.org
脚本如下:把上面学的expect应答用到了ssh的回答上,并封装为一个函数。
shell中循环语句、条件语句和自动应答语句的控制

上一篇:Linux红帽8.2系统中打开虚拟机以及命令行的使用


下一篇:Linux学习笔记-RH135之文件共享系统samba、nfs和iscsi