1. EOF 多文本输入
需求案例 1
新交付了一批机器,每台机器只分配了一块落盘 ,现在根据需求对该盘进行分区并实现挂载,如何实现?
需求分析:
对于一个盘,实现分区挂载到不同目录,通常思路有两条:
方法一: 将整块盘作为一个PV ,整合成VG卷,再根据划分不同LV卷大小分给不同目录方法二: 通过fdisk 将盘直接分割成对应需求的大小,再对磁盘初始化,完成挂载
方案解决
这里我们为了演示交互功能,选择方法二,实现脚本如下:
1 2 3 4 5 6 7 8 9 10 |
|
分析上述脚本,我们发现使用了 一个关键字 EOF
EOF
是END Of File的缩写,表示自定义终止符.既然自定义,那么EOF就不是固定的,可以随意设置别名,在linux按ctrl-d就代表EOF.EOF
一般会配合cat
能够多行文本输出.
其用法如下:
<<EOF //开始
.... //需要输入的内容
EOF //结束
例如使用 cat、<<、EOF
和>
以交互方式编写bash脚本,如下所示。
1 2 3 4 5 6 |
|
合理 利用这三个,即可以完成对应多文本交互输入,例如修改用户密码,正常情况下,需要连续输入两次密码,两次密码一致才能修改成功,如下:
上面我们学会了EOF 这个关键字,那么我们试试通过它来修改密码。脚本如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
2. Expect 自动交互
需求案例 2
新交付了一批机器,需要给每台机器分发文件,如何实现?
需求分析:
远程拷贝文件常用密令是scp 或者 rsync ,但是在给每台机器传输时需要若输入密码,有的机器可能还需要输入YES,录入机器指纹信息,如下:
Expect 是在tcl基础上的一个自动化交互套件, 在一些需要交互输入指令的场景下, 可通过脚本设置自动进行交互通信. 其交互流程主要有以下5步:
0 定义变量
1 spawn启动指定脚本或命令
2 expect匹配结果关键词
3 send针对指定关键词发送指定指令
4 执行完成, 退出
但可惜的是os默认没有安装,因此需要先安装才能使用
Expect is a tcl application for automating and testing interactive applications such as telnet, ftp, passwd, fsck, rlogin, tip, etc. Expect makes it easy for a script to control another program and interact with it.
方案解决:
1. 先检查本机是否安装了expect ,如果没有安装,需要手动安装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
2 .对应功能脚本开发,本案例脚本参考如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
3. 分析上述脚本,有几个点需要说明
1 |
|
脚本文件的第一行指明expect 安装位置,具体可以参考2 中命令查看,指明脚本解析器,和Shell类似,表示程序使用Expect解析,这里与一般bash 脚本不同,因此需要注意,通常我们会将expect脚本后缀修改成exp来和bash 脚本 sh区别
set 设置变量值
set file [lindex $argv 0]
将传入的第一个参数赋给file ,类似第二、三个参数[lindex $argv 1] [lindex $argv 2]
等,后续调用时使用 $file
,和shell 一样。特殊参数:
$argc
表示传参的个数,$argv0
表示脚本的名字
spawn 表名要执行的脚本或程序命令,如ssh、scp等
格式: spawn [选项] [需要自动交互的命令或程序]
例如:spawn scp -rp $file $file2 root@192.168.31.89:/tmp
#<==执行scp命令(注意开头必须要有spawn, 否则无法实现交互)
expect
需和spawn 配合使用 ,表示匹配spawn
指定的脚本或命令的输出结果
,如果与expect
后面的字符串匹配,就执行下面的send
命令,表示对结果响应反馈
有时命令的输出提示信息有可能会变化,所以可以在expect中使用模糊匹配,比如*
。
注意:匹配的动作也可以放在下一行,这样就不需要使用{}(大括号)了
send
在expect命令匹配指定的字符串后,发送指定的字符串给系统,这些命令可以支持一些特殊转义符号,例如:\r表示回车、\n表示换行、\t表示制表符等
exp_continue
从命令的拼写就可以看出命令的作用,即让Expect程序继续匹配的意思,如果需要一次匹配多个字符串,那么不同的匹配之间就要加上exp_continue,否则expect将不会自动输入指定的字符串。最后一个的结尾就不需要加上exp_continue了,因为前面都已完成了,它是最后一个啦
exit
功能类似于Shell中的exit,即直接退出脚本,还可以利用这个命令对脚本做一些关闭前提示等工作
send_user
打印Expect脚本信息,类似Shell里的echo. 例如打印变量信息,验证数据传入是否正常
在掌握expect 基本使用方式后,我们写一个批量查看机器负载信息的小脚本,加强记忆
1 2 3 4 5 6 7 8 9 10 |
|
小试牛刀
在学习完以上两个方法,我们试着写一个脚本,结合上述两种方式,批量查看各机器目录挂载情况,并列举出来,参考脚本如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
以上两种方式就是日常在Linux Shell 脚本常用来做自动化部署,解决脚本执行过程参数交互问题,尤其expect 配合一些shell脚本执行,十分便捷。除了以上使用方式,在企业生产中,我们还会用到ansible 脚本,ansible是新出现的自动化运维工具,基于Python开发,通过调用其模块,实现批量系统配置、批量程序部署、批量运行命令等功能,有兴趣的小伙伴可以试试学习下。