使用场景
expect可以让我们实现自动登录远程机器,并且可以实现自动远程执行命令。当然若是使用不带密码的密钥验证同样可以实现自动登录和自动远程执行命令。但当不能使用密钥验证的时候,我们就没有办法了。所以,这时候只要知道对方机器的账号和密码就可以通过expect脚本实现登录和远程命令。
安装
yum install -y expect
脚本
脚本1:自动远程登录
vim 1.expect
#! /usr/bin/expectset host "192.168.36.131"set passwd "123456"spawn ssh root@$hostexpect {"yes/no" { send "yes\r"; exp_continue}"assword:" { send "$passwd\r" }}interact
先清空之前的链接
>/root/.ssh/known_hosts
加权限,然后执行,这里就实现的自动登录!
[root@cc-01 sbin]# chmod a x 1.expect [root@cc-01 sbin]# ./1.expect spawn ssh root@192.168.36.131The authenticity of host '192.168.36.131 (192.168.36.131)' can't be established.ECDSA key fingerprint is SHA256:WwqBD7lw8dAc9G m4coHW 7vYF/9Jw3rlo6cVNjXveM.ECDSA key fingerprint is MD5:d7:66:37:8a:18:e2:99:e8:49:1c:4b:60:15:7c:57:f1.Are you sure you want to continue connecting (yes/no)? yesWarning: Permanently added '192.168.36.131' (ECDSA) to the list of known hosts.root@192.168.36.131's password: Last login: Sun Oct 7 01:17:08 2018 from 192.168.36.130[root@cc-02 ~]#
脚本2:自动远程登录后,执行命令并退出
vim 2.expect
#!/usr/bin/expectset user "root"set passwd "123456"spawn ssh $user@192.168.36.131expect {"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"
执行
[root@cc-01 sbin]# chmod a x 2.expect [root@cc-01 sbin]# ./2.expect spawn ssh root@192.168.36.131root@192.168.36.131's password: Last login: Sun Oct 7 01:20:02 2018 from 192.168.36.130[root@cc-02 ~]# touch /tmp/12.txt[root@cc-02 ~]# echo 1212 > /tmp/12.txt
检测,是否执行成功
脚本3:传递参数
vim 3.expect
#!/usr/bin/expectset user [lindex $argv 0]set host [lindex $argv 1]set passwd "123456"set cm [lindex $argv 2]spawn ssh $user@$hostexpect {"yes/no" { send "yes\r"}"password:" { send "$passwd\r" }}expect "]*"send "$cm\r"expect "]*"send "exit\r"
执行
[root@cc-01 sbin]# chmod a x 3.expect [root@cc-01 sbin]# ./3.expect root 192.168.36.131 lsspawn ssh root@192.168.36.131root@192.168.36.131's password: Last login: Sun Oct 7 01:29:18 2018 from 192.168.36.130[root@cc-02 ~]# lsanaconda-ks.cfg[root@cc-02 ~]# [root@cc-01 sbin]# ./3.expect root 192.168.36.131 "ls;w;vmstat 1 5"spawn ssh root@192.168.36.131root@192.168.36.131's password: Last login: Sun Oct 7 01:36:54 2018 from 192.168.36.130[root@cc-02 ~]# ls;w;vmstat 1 5anaconda-ks.cfg 01:37:45 up 3:24, 3 users, load average: 0.00, 0.01, 0.05USER TTY FROM LOGIN@ IDLE JCPU PCPU WHATroot tty1 01:14 23:21 0.02s 0.02s -bashroot pts/0 192.168.36.1 01:02 7:13 0.06s 0.06s -bashroot pts/1 192.168.36.130 01:37 0.00s 0.01s 0.00s wprocs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 2 0 0 772812 2108 128168 0 0 9 1 58 66 0 0 100 0 0 0 0 0 772772 2108 128204 0 0 0 0 108 114 0 1 99 0 0 0 0 0 772772 2108 128204 0 0 0 0 106 106 0 0 100 0 0 0 0 0 772772 2108 128204 0 0 0 0 88 85 0 0 100 0 0 0 0 0 772772 2108 128204 0 0 0 0 96 91 0 0 100 0 0[root@cc-02 ~]# [root@cc-01 sbin]#
脚本4:自动同步文件
vim 4.expect
#!/usr/bin/expectset passwd "123456"spawn rsync -av root@192.168.36.131:/tmp/12.txt /tmp/expect {"yes/no" { send "yes\r"}"password:" { send "$passwd\r" }}expect eof
执行
[root@cc-01 sbin]# chmod a x 4.expect [root@cc-01 sbin]# ./4.expect spawn rsync -av root@192.168.36.131:/tmp/12.txt /tmp/root@192.168.36.131's password: receiving incremental file list12.txtsent 43 bytes received 97 bytes 280.00 bytes/sectotal size is 5 speedup is 0.04[root@cc-01 sbin]# cat /tmp/12.txt 1212
expect eof;interact 一定要加上,不然就执行不完我们的语句。
set timeout 设置超时时间,-1为永久
脚本5:指定host和要同步的文件
vim 5.expect
#!/usr/bin/expectset passwd "123456"set host [lindex $argv 0]set file [lindex $argv 1]spawn rsync -av $file root@$host:$fileexpect {"yes/no" { send "yes\r"}"password:" { send "$passwd\r" }}expect eof
执行
[root@cc-01 sbin]# chmod a x 5.expect [root@cc-01 sbin]# ./5.expect 192.168.36.131 "/tmp/12.txt"spawn rsync -av /tmp/12.txt root@192.168.36.131:/tmp/12.txtroot@192.168.36.131's password: sending incremental file listsent 45 bytes received 12 bytes 38.00 bytes/sectotal size is 5 speedup is 0.09
构建文件分发系统需求背景
对于大公司而言,肯定时不时会有网站或者配置文件更新,而且使用的机器肯定也是好多台,少则几台,多则几十甚至上百台。所以,自动同步文件是至关重要的。
实现思路
首先要有一台模板机器,把要分发的文件准备好,然后只要使用expect脚本批量把需要同步的文件分发到目标机器即可。
核心命令
rsync -av --files-from=list.txt / root@host:/
文件分发系统的实现
vim rsync.expect
#!/usr/bin/expectset passwd "123456"set host [lindex $argv 0]set file [lindex $argv 1]spawn rsync -av --files-from=$file / root@$host:/expect {"yes/no" { send "yes\r"}"password:" { send "$passwd\r" }}expect eof
vim /tmp/ip.list 为需要同步的远程机器IP
192.168.36.131127.0.0.1
vim /tmp/list.txt 为同步的文件路径
/tmp/12.txt/root/shell/ip.sh/root/111/1.txt
vim rsync.sh 执行脚本
#!/bin/bashfor ip in `cat /tmp/ip.list`do./rsync.expect $ip /tmp/list.txtdone
执行
[root@cc-01 sbin]# chmod a x rsync.expect [root@cc-01 sbin]# sh -x rsync.sh cat /tmp/ip.list for ip in '`cat /tmp/ip.list`' ./rsync.expect 192.168.36.131 /tmp/list.txtspawn rsync -av --files-from=/tmp/list.txt / root@192.168.36.131:/root@192.168.36.131's password: building file list ... rsync: link_stat "/root/111/1.txt " failed: No such file or directory (2)doneroot/tmp/sent 148 bytes received 22 bytes 340.00 bytes/sectotal size is 63 speedup is 0.37rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1178) [sender=3.1.2] for ip in '`cat /tmp/ip.list`' ./rsync.expect 127.0.0.1 /tmp/list.txtspawn rsync -av --files-from=/tmp/list.txt / root@127.0.0.1:/The authenticity of host '127.0.0.1 (127.0.0.1)' can't be established.ECDSA key fingerprint is SHA256:WwqBD7lw8dAc9G m4coHW 7vYF/9Jw3rlo6cVNjXveM.ECDSA key fingerprint is MD5:d7:66:37:8a:18:e2:99:e8:49:1c:4b:60:15:7c:57:f1.Are you sure you want to continue connecting (yes/no)? yesWarning: Permanently added '127.0.0.1' (ECDSA) to the list of known hosts.root@127.0.0.1's password: [root@cc-01 sbin]#
命令批量执行
vim exe.expect
#!/usr/bin/expectset host [lindex $argv 0]set passwd "123456"set cm [lindex $argv 1]spawn ssh root@$hostexpect {"yes/no" { send "yes\r"}"password:" { send "$passwd\r" }}expect "]*"send "$cm\r"expect "]*"send "exit\r"
vim exe.sh
for ip in `cat /tmp/ip.list`do echo $ip ./exe.expect $ip "w;free -m;ls /tmp"done
执行
[root@cc-01 sbin]# chmod a x exe.expect [root@cc-01 sbin]# sh -x exe.sh cat /tmp/ip.list for ip in '`cat /tmp/ip.list`' echo 192.168.36.131192.168.36.131 ./exe.expect 192.168.36.131 'w;free -m;ls /tmp'spawn ssh root@192.168.36.131root@192.168.36.131's password: Last login: Sun Oct 7 01:37:45 2018 from 192.168.36.130[root@cc-02 ~]# w;free -m;ls /tmp 02:45:30 up 4:31, 3 users, load average: 0.00, 0.01, 0.05USER TTY FROM LOGIN@ IDLE JCPU PCPU WHATroot tty1 01:14 1:31m 0.02s 0.02s -bashroot pts/0 192.168.36.1 01:02 47:06 0.06s 0.06s -bashroot pts/1 192.168.36.130 02:45 0.00s 0.00s 0.00s w total used free shared buff/cache availableMem: 974 92 753 7 127 732Swap: 2047 0 204712.txt systemd-private-69bd6363742e4d5fa8acdcda8e7e5678-chronyd.service-q1SZkI[root@cc-02 ~]# for ip in '`cat /tmp/ip.list`' echo 127.0.0.1127.0.0.1 ./exe.expect 127.0.0.1 'w;free -m;ls /tmp'spawn ssh root@127.0.0.1root@127.0.0.1's password: Last failed login: Sun Oct 7 02:36:22 CST 2018 from localhost on ssh:nottyThere were 2 failed login attempts since the last successful login.Last login: Sun Oct 7 01:59:35 2018[root@cc-01 ~]# w;free -m;ls /tmp 02:45:30 up 4:32, 4 users, load average: 0.00, 0.01, 0.05USER TTY FROM LOGIN@ IDLE JCPU PCPU WHATroot tty1 01:59 46:02 0.02s 0.02s -bashroot pts/0 192.168.36.1 01:02 2.00s 0.31s 0.00s /usr/bin/expect ./exe.expect 127.0.0.1 w;frroot pts/1 192.168.36.1 01:16 15:38 0.16s 0.16s -bashroot pts/3 localhost 02:45 0.00s 0.01s 0.00s w total used free shared buff/cache availableMem: 974 140 460 7 373 660Swap: 2047 0 204712.txt systemd-private-8e811640829b4077883431f61a93c3f6-chronyd.service-2YJZoL1.log systemd-private-b00b7d3acc854463945334b653d81b01-chronyd.service-1zBY3Lcc.sock systemd-private-b0559a02f4d4465c83e8d26e8f9b5d77-chronyd.service-2CCL3Fip.list systemd-private-ff47bd5716cf486aafcf7d9280c40412-chronyd.service-DcJiqslist.txt vmware-rootphp-fcgi.sock[root@cc-01 ~]# [root@cc-01 sbin]#