二十二、分发系统介绍
expect是一个免费的编程工具语言,用来实现自动和交互式任务进行通信,而无需人的干预。expect是在Tcl基础上创建起来的。
二十三、expect脚本远程登录
安装expect
[root@node2 ~]# yum install expect -y
远程登录脚本:
[root@node2 ~]# vim remotelogin.expect
#!/usr/bin/expect
set host "192.168.10.205"
set passwd "123456"
spawn ssh root@$host
expect {
"yes/no" { send "yes\r";exp_continue }
"assword:" { send "$passwd\r" }
}
interact
执行脚本:
[root@node2 ~]# chmod +x remotelogin.expect
[root@node2 ~]# ./remotelogin.expect
spawn ssh root@192.168.10.205
The authenticity of host '192.168.10.205 (192.168.10.205)' can't be established.
ECDSA key fingerprint is SHA256:bfXUezrOQimsSXepM09lXgx/Pol5MJvtvgOU7K+wdWQ.
ECDSA key fingerprint is MD5:a2:9c:64:2f:7b:2b:93:26:fa:d6:b1:48:5a:6d:d8:42.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.10.205' (ECDSA) to the list of known hosts.
root@192.168.10.205's password:
Last login: Fri Jul 20 23:13:17 2018 from 192.168.10.1
[root@node1 ~]#
OK,登录成功。
二十四、expect脚本远程执行命令
脚本如下:
[root@node2 ~]# vim expectdemo01.expect
#!/usr/bin/expect
set user "root"
set passwd "123456"
set host "192.168.10.205"
spawn ssh $user@$host
expect {
"yes/no" { send "yes\r";exp_continue }
"password:" { send "$passwd\r"}
}
expect "]*"
send "touch /tmp/12.txt\r"
expect "]*"
send "echo haha > /tmp/12.txt\r"
expect "]*"
send "exit\r"
执行:
[root@node2 ~]# chmod +x expectdemo01.expect
[root@node2 ~]# ./expectdemo01.expect
spawn ssh root@192.168.10.205
root@192.168.10.205's password:
Last login: Sat Jul 21 17:46:55 2018 from 192.168.10.206
[root@node1 ~]# touch /tmp/12.txt
[root@node1 ~]# echo haha > /tmp/12.txt
[root@node1 ~]# [root@node2 ~]#
该脚本远程登录192.168.10.205,创建/tmp/12.txt文件,然后退出。
二十五、expect脚本传递参数
脚本:
#!/usr/bin/expect
set user [lindex $argv 0]
set host [lindex $argv 1]
set passwd "123456"
set cm [lindex $argv 2]
spawn ssh $user@$host
expect {
"yes/no" { send "yes\r";exp_continue }
"password:" { send "$passwd\r"}
}
expect "]*"
send "$cm\r"
set timeout 5
expect "]*"
send "exit\r"
set timeout 5:设置超时时间,如是-1则不会超时
执行脚本:
[root@node2 ~]# chmod +x expectdemo02.expect
[root@node2 ~]# ./expectdemo02.expect root 192.168.10.205 ls
spawn ssh root@192.168.10.205
Last login: Sat Jul 21 20:06:38 2018 from 192.168.10.206
[root@node1 ~]# ls
anaconda-ks.cfg mariadb-10.3.7 php-7.2.7 zabbix-3.4.11
auto_install_zabbix_lnmp.sh mariadb-10.3.7.tar.gz php-7.2.7.tar.gz zabbix-3.4.11.tar.gz
libmcrypt-2.5.8 nginx-1.14.0 py
libmcrypt-2.5.8.tar.gz nginx-1.14.0.tar.gz Python-3.7.0.tgz
[root@node1 ~]# [root@node2 ~]#
OK,执行成功。
二十六、expect脚本同步文件
脚本:
[root@node2 ~]# vim expectdemo03.expect
#!/usr/bin/expect
set passwd "123456"
spawn rsync -av root@192.168.10.205:/tmp/12.txt /tmp/
expect {
"yes/no" { send "yes\r";exp_continue }
"password:" { send "$passwd\r" }
}
expect eof
执行:
[root@node2 ~]# chmod +x expectdemo03.expect
[root@node2 ~]# ./expectdemo03.expect
spawn rsync -av root@192.168.10.205:/tmp/12.txt /tmp/
receiving incremental file list
12.txt
sent 43 bytes received 96 bytes 92.67 bytes/sec
total size is 5 speedup is 0.04
expect: spawn id exp6 not open
while executing
"expect eof"
(file "./expectdemo03.expect" line 12)
[root@node2 ~]#
二十七、expect脚本指定host和要同步的文件
脚本:
[root@node2 ~]# vim expectdemo04.expect
#!/usr/bin/expect
set passwd "123456"
set host [lindex $argv 0]
set file [lindex $argv 1]
spawn rsync -av $file root@$host:$file
expect {
"yes/no" { send "yes\r" }
"password:" { send "$passwd\r" }
}
expect eof
测试执行:
[root@node2 ~]# chmod +x expectdemo04.expect
[root@node2 ~]# ./expectdemo04.expect 192.168.10.205 /root/for.sh
spawn rsync -av /root/for.sh root@192.168.10.205:/root/for.sh
sending incremental file list
for.sh
sent 174 bytes received 35 bytes 139.33 bytes/sec
total size is 82 speedup is 0.39
expect: spawn id exp6 not open
while executing
"expect eof"
(file "./expectdemo04.expect" line 13)
[root@node2 ~]#
登录192.168.10.205看看:
[root@node2 ~]# ssh 192.168.10.205
Last login: Sat Jul 21 20:28:17 2018 from 192.168.10.206
[root@node1 ~]# ls
anaconda-ks.cfg libmcrypt-2.5.8.tar.gz nginx-1.14.0.tar.gz Python-3.7.0.tgz
auto_install_zabbix_lnmp.sh mariadb-10.3.7 php-7.2.7 zabbix-3.4.11
for.sh mariadb-10.3.7.tar.gz php-7.2.7.tar.gz zabbix-3.4.11.tar.gz
libmcrypt-2.5.8 nginx-1.14.0 py
[root@node1 ~]#
OK,for.sh文件已同步过来
二十八、expect传输ssh公钥
1、生成密钥对
[root@node2 ~]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:lj4GyvqmmHzJbY4KlK2xLXP54/bXptI20iHB8xipdkQ root@node2
The key's randomart image is:
+---[RSA 2048]----+
| |
| E |
| o . |
| o B . |
| + . + S |
|. =..+ B o |
|.=.+* . B o |
|oo+=+= + B o |
|oo==*+o.=.+ |
+----[SHA256]-----+
[root@node2 ~]#
2、将公钥传给远程客户端
脚本:
#!/usr/bin/expect
set host "192.168.10.205"
set passwd "123456"
spawn ssh-copy-id $host
expect {
"yes/no" { send "yes\r";exp_continue }
"password:" { send "$passwd\r"}
}
interact
执行脚本:
[root@node2 ~]# chmod +x ssh.expect
[root@node2 ~]# ./ssh.expect
spawn ssh-copy-id 192.168.10.205
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@192.168.10.205's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh '192.168.10.205'"
and check to make sure that only the key(s) you wanted were added.
[root@node2 ~]#
3、测试:
[root@node2 ~]# ssh 192.168.10.205
Last login: Sat Jul 21 19:52:45 2018 from 192.168.10.206
[root@node1 ~]#
OK,可以免密登录了。
二十九、构建文件分发系统
需求背景:对于大公司而言,肯定时不时会有网站或配置文件更新,而且使用的机器也好几台,所以,自动同步文件就至关重要了。
实现思路:首先有一台模版机器,把要分发的文件准备好,然后使用expect脚本批量把需要的文件分发到目标机器即可。
核心命令:rsync -avR --files-from=list.txt / root@host:/
1、expect脚本:
[root@node2 ~]# vim expectdemo05.expect
#!/usr/bin/expect
set passwd "123456"
set host [lindex $argv 0]
set file [lindex $argv 1]
spawn rsync -avR --files-from=$file / root@$host:/
expect {
"yes/no" { send "yes\r"}
"password:" { send "$passwd\r"}
}
expect eof
[root@node2 ~]# chmod +x expectdemo05.expect
2、需要同步的文件列表:
list.txt内容:该文件的内容放的是文件的绝对路径
[root@node2 ~]# vim /tmp/list.txt
/tmp/12.txt
/root/for.sh
/root/expectdemo01.expect
/root/expectdemo02.expect
/root/expectdemo03.expect
/root/expectdemo04.expect
3、ip列表:ip.txt,存放的是ip
[root@node2 ~]# vim /tmp/ip.txt
192.168.10.205
192.168.10.200
4、创建遍历ip列表的脚本
[root@node2 ~]# vim rsync.sh
#!/bin/bash
for rip in `cat /tmp/ip.txt`
do
echo $rip
./expectdemo05.expect $rip /tmp/list.txt
done
执行该脚本:
[root@node2 ~]# sh rsync.sh
192.168.10.205
spawn rsync -av --files-from=/tmp/list.txt / root@192.168.10.205:/
building file list ... done
root/
tmp/
sent 237 bytes received 22 bytes 518.00 bytes/sec
total size is 1,089 speedup is 4.20
expect: spawn id exp6 not open
while executing
"expect eof"
(file "./expectdemo05.expect" line 13)
192.168.10.200
spawn rsync -av --files-from=/tmp/list.txt / root@192.168.10.200:/
root@192.168.10.200's password:
building file list ... done
root/
tmp/
sent 237 bytes received 22 bytes 172.67 bytes/sec
total size is 1,089 speedup is 4.20
[root@node2 ~]#
三十、批量远程执行命令
1、expect脚本:
[root@node2 ~]# vim exec.expect
#!/usr/bin/expect
set host [lindex $argv 0]
set passwd "123456"
set cm [lindex $argv 1]
spawn ssh root@$host
expect {
"yes/no" { send "yes\r"}
"password:" { send "$passwd\r"}
}
expect "]*"
send "$cm\r"
expect "]*"
send "exit\r"
[root@node2 ~]# chmod +x exec.expect
2、shell脚本
[root@node2 ~]# vim exec.sh
#!/bin/bash
for rip in `cat /tmp/ip.txt`
do
echo $rip
./exec.expect $rip "hostname"
done
执行脚本:
[root@node2 ~]# sh exec.sh
192.168.10.205
spawn ssh root@192.168.10.205
Last login: Sat Jul 21 21:01:41 2018 from 192.168.10.206
[root@node1 ~]# hostname
node1
[root@node1 ~]# 192.168.10.200
spawn ssh root@192.168.10.200
root@192.168.10.200's password:
Last failed login: Sat Jul 21 20:59:02 CST 2018 from 192.168.10.206 on ssh:notty
There were 2 failed login attempts since the last successful login.
Last login: Fri Jul 20 23:05:56 2018 from 192.168.10.1
[root@node3 ~]# hostname
node3
[root@node3 ~]# [root@node2 ~]#