shell项目-分发系统-expect讲解
20.27 分发系统介绍
使用场景:
假如公司的业务做得越来越大,APP后端服务端所使用的编程语言是php,要想运行这个环境运行php代码,需要搭建lamp,lnmp的环境,最后还需要把代码上传到服务器上面。
在平时工作中,业务不断的迭代,有新的功能出现,这时候就需要更改代码,一台机器还好,甚至还可以在服务器上面更改,但是这样不规范,若干台,两三台的量还可以接受,如果机器特别多,甚至上百台的时候,这上百台机器存储的都是公司的站点。比如一个接口,APP访问量很大,APP需要调用服务端的接口,假如这个接口需要五十台机器去承载,那这时候就需要去搞一个分发系统了,能够让每天,每段时间更新的代码,分别的分布到这五十台机器上面去。
expect介绍
可以说是一种脚本语言,它和shell比较相似,它可以实现传输文件,远程执行命令(不需要输入密码)
它其实是一种上线代码的工具。
上线:开发的代码,发布到线上环境。
准备工作以及过程:
准备一台模板机器,这台机器上面的代码是最新的,准备要上线的代码。
比如准备给50台机器上线,这50台机器的ip地址,用户和密码都需要知道
使用expect脚本,借助于rsync把这些代码给推送到这50台机器上面去。假如需要在某机器上面执行命令,还可以远程执行这些命令。
就是这样的一个过程。
20.28 expect脚本远程登录
1 安装expect
[root@centos7-01 ~]# yum install -y expect
2 编写expect脚本
目的:自动远程登录,并执行命令
[root@centos7-01 ~]# cd /usr/local/sbin/ #! /usr/bin/expect set host "192.168.189.129" set passwd "?????" #此处输入你的登录密码. spawn ssh root@$host expect { "yes/no" { send "yes\r"; exp_continue} "password:" { send "$passwd\r" } } interact
脚本解释:
set host "192.168.189.129" set passwd "?????" spawn ssh root@$host #远程登录的主机,以及密码,set host=$host,在except里,set设定变量 #spwan后接的是系统的shell命令,ssh远程登录,root@$host利用root登录进去 expect { "yes/no" { send "yes\r"; exp_continue} "password:" { send "$passwd\r" } } interact #这是核心执行语句 "yes/no"表示第一次远程登录192.168.189.129,会提示"yes/no"。因为第一次登录,本机的/root/.ssh/know_hosts文件会误认为这是一台陌生的机器,严格上可能是不安全,所以会提示。 "yes/no" { send "yes\r"; exp_continue} #expect截取系统的提示,当遇到提示"yes/no"的时候,发送yes(yes\r,\表示回车键), exp_continue表示继续 "password:" { send "$passwd\r" } #expect截取系统的提示,当遇到提示"password:"的时候,把密码(set passwd的变量)发送过去, #expect支持用户交互 #interact结束
3 添加执行权限
[root@centos7-01 sbin]# chmod a+x 1.expect
4 执行脚本
[root@centos7-01 sbin]# ./1.expect spawn ssh [email protected] [email protected]'s password: Last login: Wed Jun 6 15:27:39 2018 from 192.168.189.1 [root@centos7-02 ~]#
5 查看ip地址
[root@centos7-02 ~]# ifconfig ens33: flags=4163mtu 1500 inet 192.168.189.129 netmask 255.255.255.0 broadcast 192.168.189.255 inet6 fe80::b485:96d0:c537:251e prefixlen 64 scopeid 0x20 ether 00:0c:29:73:7c:4c txqueuelen 1000 (Ethernet) RX packets 266 bytes 27149 (26.5 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 257 bytes 25678 (25.0 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
成功登录192.168.189.129,主机名也变了
20.29 expect脚本远程执行命令
1 必须在本机编写脚本,所以必须退出当前远程连接
[root@centos7-02 ~]# 登出 Connection to 192.168.189.129 closed.
2 改写脚本2.expect
目的:自动远程登录后,执行命令并退出
#!/usr/bin/expect set user "root" set passwd "远程登录的密码" spawn ssh [email protected] expect { "yes/no" { send "yes\r"; exp_continue} "password:" { send "$passwd\r" } } expect "]*" send "touch /tmp/12.txt\r" expect "]*" send "echo 1212 > /tmp/12.txt\r" expect "]*" send "exit\r"
脚本解释:
#脚本分为2段,第一段是作为远程连接,第二段是远程登录后的操作。
expect "]*"
#expect "]*"这里的*表示用户的标识,#表示root用户,$表示普通用户
send "touch /tmp/12.txt\r"
#执行touch /tmp/12.txt\r命令,\r表示回车,这里算是确认执行的意思
expect "]*" send "echo 1212 > /tmp/12.txt\r"
#执行echo 1212 > /tmp/12.txt\r,\r表示回车,
expect "]*" send "exit\r"
#exit表示退出,登出
#interact与exit的区别:
interact 结束except脚本,但是它还停留在远程登录的机器上
exit 执行脚本结束,并退出当前登录状态
如果2个参数都不加,远程登录后会马上退出登录状态
3 给予脚本执行权限
[root@centos7-01 sbin]# chmod a+x 2.expect
4 执行脚本
[root@centos7-01 sbin]# ./2.expect spawn ssh [email protected] [email protected]'s password: Last login: Wed Jun 6 15:51:19 2018 from 192.168.189.128 [root@centos7-02 ~]# touch /tmp/12.txt [root@centos7-02 ~]# echo 1212 > /tmp/12.txt [root@centos7-02 ~]# [root@centos7-01 sbin]#
5 检查当前所登录的机器
[root@centos7-01 sbin]# ifconfig ens33: flags=4163mtu 1500 inet 192.168.189.128 netmask 255.255.255.0 broadcast 192.168.189.255 inet6 fe80::20c:29ff:fe15:5353 prefixlen 64 scopeid 0x20 ether 00:0c:29:15:53:53 txqueuelen 1000 (Ethernet) RX packets 6552 bytes 6160724 (5.8 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 5049 bytes 447825 (437.3 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
进入到128,已退出129
6 进入129查看刚刚执行的命令
执行刚刚建立的远程登录脚本
[root@centos7-01 sbin]# ./1.expect spawn ssh [email protected] [email protected]'s password: Last login: Wed Jun 6 16:18:03 2018 from 192.168.189.128
查看远程登录后的执行结果
[root@centos7-02 ~]# ls -l /tmp/12.txt -rw-r--r-- 1 root root 5 6月 6 16:18 /tmp/12.txt [root@centos7-02 ~]# cat !$ cat /tmp/12.txt 1212
20.30 expect脚本传递参数
1 编写脚本3.expect
[root@centos7-01 sbin]# vim 3.expect #!/usr/bin/expect set user [lindex $argv 0] set host [lindex $argv 1] set passwd "input your password...." set cm [lindex $argv 2] spawn ssh $user@$host expect { "yes/no" { send "yes\r"} "password:" { send "$passwd\r" } } expect "]*" send "$cm\r" expect "]*" send "exit\r"
参数解释:
set user [lindex $argv 0] 把第一个参数设为user
set host [lindex $argv 1] 把第二个参数设为host
set cm [lindex $argv 2] 把第三个参数设为cm(执行的命令)
2 给予3.expect执行权限
[root@centos7-01 sbin]# chmod a+x 3.expect
3 执行脚本
[root@centos7-01 sbin]# ./3.expect root 192.168.189.129 ls spawn ssh [email protected] [email protected]'s password: Last login: Wed Jun 6 16:19:53 2018 from 192.168.189.128 [root@centos7-02 ~]# ls 1.txt 2a.txt 3.txt aa.txt a.txt network-test 22.txt 2.txt a2.txt anaconda-ks.cfg A.txt
解释说明:
# ./3.expect root 192.168.189.129 ls
刚刚脚本定义了配置参数,执行脚本后的第一个参数是user 第二个是host主机,第三个参数是命令,那么对应起来就是一目了然了。
3.1 传递执行多条命令
多个传递命令用""标起,
传递命令分别是:ls;w;cd /tmp/;pwd
./3.expect root 192.168.189.129 "ls;w;cd /tmp/;pwd" spawn ssh [email protected] [email protected]'s password: Last login: Wed Jun 6 16:53:24 2018 from 192.168.189.128 [root@centos7-02 ~]# ls;w;cd /tmp/;pwd 1.txt 2a.txt 3.txt aa.txt a.txt network-test 22.txt 2.txt a2.txt anaconda-ks.cfg A.txt 16:54:40 up 1:28, 2 users, load average: 0.00, 0.01, 0.05 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT root pts/0 192.168.189.1 15:27 1:27m 0.01s 0.01s -bash root pts/1 192.168.189.128 16:54 0.00s 0.01s 0.00s w /tmp
3.2 输出正常.done.