-
20.31 expect脚本同步文件
- 在一台机器上把文件同步到多台机器上
- 自动同步文件
[root@aming-01 ~]# cd /usr/local/sbin [root@aming-01 sbin]# ls 1.expect 2.expect 3.expect check_ng.sh lvs_dr.sh lvs_nat.sh mon nginx_logrotate.sh [root@aming-01 sbin]# vi 4.expect
#!/usr/bin/expect
set passwd "123456"
spawn rsync -av root@192.168.202.132:/tmp/12.txt /tmp/
expect {
"yes/no" { send "yes
"}
"password:" { send "$passwd
" }
}
expect eof
~
:wq
- 加上执行权限,再来执行脚本
[root@aming-01 sbin]# vi 4.expect
[root@aming-01 sbin]# chmod a+x 4.expect
[root@aming-01 sbin]# ./4.expect
[root@aming-01 sbin]# ./4.expect
spawn rsync -av root@192.168.202.132:/tmp/12.txt /tmp/
root@192.168.202.132's password:
receiving incremental file list
12.txt
sent 30 bytes received 84 bytes 228.00 bytes/sec
total size is 5 speedup is 0.04
[root@aming-01 sbin]#
[root@aming-01 sbin]# cat /tmp/12.txt
1212
[root@aming-01 sbin]#
- 如果把脚本里面的 expect eof 注释掉会有什么样的差异
[root@aming-01 sbin]# vi 4.expect
[root@aming-01 sbin]# ./4.expect
spawn rsync -av root@192.168.202.132:/tmp/12.txt /tmp/
root@192.168.202.132's password: [root@aming-01 sbin]# rm -f /tmp/12.txt
[root@aming-01 sbin]# ./4.expect
spawn rsync -av root@192.168.202.132:/tmp/12.txt /tmp/
root@192.168.202.132's password: [root@aming-01 sbin]#
[root@aming-01 sbin]# ls /tmp/12.txt
ls: 无法访问/tmp/12.txt: 没有那个文件或目录
[root@aming-01 sbin]#
- 还没来得及传输就退出了,仅仅是输入完密码,就停止了,者与肯定不对
- 所以需要加上expect eof (表示最起码能给你足够的时间去做一些操作,比如传输文件的时候,需要反应一会儿,)如果不加这个,有可能仅仅是登录就退出来,或者没有登录成功,
# 20.32 expect脚本指定host和要同步的文件
- set timeout 定义超时时间(单位为 秒) -1 为永远不超时
- 可以指定具体的秒数,比如5秒
[root@aming-01 sbin]# vi 3.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
"}
"password:" { send "$passwd
" }
}
expect "]"
send "$cm
"
set timeout 5
expect "]"
send "exit
"
~
~
~
~
~
~
~
~
~
~
:wq
[root@aming-01 sbin]# ./3.expect root 192.168.202.132 "vmstat 1"
spawn ssh root@192.168.202.132
root@192.168.202.132's password:
Last failed login: Wed Nov 29 21:56:17 CST 2017 from 192.168.202.130 on ssh:notty
There were 10 failed login attempts since the last successful login.
Last login: Wed Nov 29 19:52:32 2017 from 192.168.202.1
[root@aming-02 ~]# vmstat 1
procs -----------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 169360 876 280408 0 0 25 5 66 130 0 0 99 0 0
0 0 0 169360 876 280440 0 0 0 4 72 138 0 0 100 0 0
0 0 0 169360 876 280440 0 0 0 0 79 135 0 0 100 0 0
0 0 0 169360 876 280440 0 0 0 0 60 122 0 0 100 0 0
0 0 0 169360 876 280440 0 0 0 8 77 138 0 1 99 0 0
[root@aming-01 sbin]#
- 如果是set timeout -1 就是永久了
expect "]"
send "$cm
"
set timeout -1
expect "]"
send "exit
"
~
:wq
[root@aming-01 sbin]# vi 3.expect
[root@aming-01 sbin]# ./3.expect root 192.168.202.132 "vmstat 1"
spawn ssh root@192.168.202.132
root@192.168.202.132's password:
Last login: Wed Nov 29 22:17:40 2017 from 192.168.202.130
[root@aming-02 ~]# vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
9 0 0 169484 876 280460 0 0 25 5 66 130 0 0 99 0 0
0 0 0 169484 876 280444 0 0 0 0 63 125 0 0 100 0 0
0 0 0 169484 876 280444 0 0 0 0 66 118 1 1 98 0 0
0 0 0 169484 876 280444 0 0 0 0 58 113 0 0 100 0 0
0 0 0 169484 876 280444 0 0 0 0 61 115 0 0 100 0 0
^C[root@aming-01 sbin]#
- 只能手动ctrl c 结束
- 指定host和要同步的文件
[root@aming-01 sbin]# vi 5.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
"}
"password:" { send "$passwd
" }
}
expect eof
~
~
~
~
~
~
~
~
~
~
~
~
~
:wq
- 先把之前的那个文件同步过来再来执行这个脚本
[root@aming-01 sbin]# vi 4.expect
#!/usr/bin/expect
set passwd "123456"
spawn rsync -av root@192.168.202.132:/tmp/12.txt /tmp/
expect {
"yes/no" { send "yes
"}
"password:" { send "$passwd
" }
}
expect eof
~
~
~
"4.expect" 8L, 173C
[root@aming-01 sbin]# vi 4.expect
[root@aming-01 sbin]# ./4.expect
spawn rsync -av root@192.168.202.132:/tmp/12.txt /tmp/
root@192.168.202.132's password:
receiving incremental file list
12.txt
sent 30 bytes received 84 bytes 76.00 bytes/sec
total size is 5 speedup is 0.04
- 先加上执行权限,然后下面执行我们的脚本
[root@aming-01 sbin]# chmod a+x 5.expect
[root@aming-01 sbin]# ./5.expect 192.168.202.132 "/tmp/12.txt"
spawn rsync -av /tmp/12.txt root@192.168.202.132:/tmp/12.txt
root@192.168.202.132's password:
sending incremental file list
sent 31 bytes received 12 bytes 86.00 bytes/sec
total size is 5 speedup is 0.12
[root@aming-01 sbin]#
# 20.33 构建文件分发系统
- 需求背景
- 对于大公司而言,肯定时不时会有网站或者配置文件更新,而且使用的机器肯定也是好多台,少则几台,多则几十甚至上百台。所以,自动同步文件是至关重要的。
- 实现思路
- 首先要有一台模板机器,把要分发的文件准备好,然后只要使用expect脚本批量把需要同步的文件分发到目标机器即可。
- 核心命令
- rsync -av --files-from=list.txt / root@host:/
- 使用rsync 的 –files参数,可以实现调用文件里面的列表,进行多个文件远程传输,进而实现文件分发 文件列表的路径必须要以全局路径,绝对路径
- 文件分发系统的实现
[root@aming-01 sbin]# vi rsync.expect
#!/usr/bin/expect
set 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
"}
"password:" { send "$passwd
" }
}
expect eof
~
:wq
- 现在root 下面创建 目录111.下面创建222,在下面创建一个lll.txt
[root@aming-01 ~]# ls /root/111/
[root@aming-01 ~]# cd 111
[root@aming-01 111]# mkdir 222
[root@aming-01 111]# cd 222
[root@aming-01 222]# ls
[root@aming-01 222]# touch lll.txt
[root@aming-01 ~]# ls /root/111/222/lll.txt
/root/111/222/lll.txt
- 这个时候还需要定义file list.txt
[root@aming-01 ~]# fg
vi /tmp/list.txt (wd: /usr/local/sbin)
/tmp/12.txt
/root/shell/1.sh
/root/111/222/lll.txt
~
~
:wq
[root@aming-01 ~]# cd /usr/local/sbin
[root@aming-01 sbin]# vi /tmp/list.txt
[root@aming-01 sbin]# cat /tmp/list.txt
/tmp/12.txt
/root/shell/1.sh
/root/111/222/lll.txt
[root@aming-01 sbin]#
- 再来编辑下rsync.expect
[root@aming-01 sbin]# vi rsync.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
"}
"password:" { send "$passwd
" }
}
expect eof
:wq
- rsync -avR --files-from=$file / root@$host:/ 内容里加了一个-R ,因为不能保证对方机器上有相同的路径,加上-R就会 自动创建没有的路径
- 1.同步的路径,需要保证对方机器也有这个相同的路径,如果没有路径,需要使用 -R 创建路径
- 咱们的list文件也有了,还需要一个ip.list,因为你的远程同步的机器不止一台,所以还要加上一个ip列表
- 2.因为实现分发系统,肯定是因为需要分发的机器数量过大,所以,定义好了 文件 的 list 列表文件以后, 还需要配置 ip 的列表文件
- 创建需要同步IP地址的列表文件
[root@aming-01 sbin]# vi /tmp/ip.txt
192.168.202.132
127.0.0.1
~
~
:wq
- 做这个expect脚本保证俩台机器的密码是一样的,如果不一样,就只能挨个去定义每台机器的密码
- 下面还需要创建一个rsync.sh
- 这个sh 的目的,就是遍历一下 ip列表文件中的 ip地址
[root@aming-01 sbin]# vi rsync.sh
#!/bin/bash
for ip in cat /tmp/ip.list
do
./rsync.expect $ip /tmp/file.list
done
~
~
:wq
- 把rsync。expect加上执行权限,
- 把ip.txt 文件名改为ip.list
- 再来执行脚本rsync.sh 看下过程 sh -x
[root@aming-01 sbin]# vi rsync.sh
[root@aming-01 sbin]# chmod a+x rsync.expect
[root@aming-01 sbin]# mv /tmp/ip.txt /tmp/ip.list
[root@aming-01 sbin]# sh -x rsync.sh
++ cat /tmp/ip.list
- for ip in '
cat /tmp/ip.list
' - ./rsync.expect 192.168.202.132 /tmp/file.list
spawn rsync -avR --files-from=/tmp/file.list / root@192.168.202.132:/
root@192.168.202.132's password:
building file list ... rsync: link_stat "/root/shell/1.sh" failed: No such file or directory (2)
done
root/
root/111/
root/111/222/
root/111/222/lll.txt
tmp/
sent 173 bytes received 43 bytes 432.00 bytes/sec
total size is 5 speedup is 0.02
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1052) [sender=3.0.9]
- for ip in '
cat /tmp/ip.list
' - ./rsync.expect 127.0.0.1 /tmp/file.list
spawn rsync -avR --files-from=/tmp/file.list / 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 00:22:2a:58:d5:c3:79:dc:8b:d7:b1:91:5c:ec:27:83.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '127.0.0.1' (ECDSA) to the list of known hosts.
root@127.0.0.1's password: [root@aming-01 sbin]# - 再去远程机器上aming-02 192.168.202.132 上面看下有没有那个ll1.txt文件
[root@aming-02 ~]# ls -l /root/111/222/lll.txt -rw-r--r-- 1 root root 0 11月 29 22:40 /root/111/222/lll.txt [root@aming-02 ~]#
-
是由的,就是通过rsync -avR --files-from=list.txt / root@host:/ 来实现的文件,表示传输一个文件列表里的文件
- 最重要的,expect脚本 必须加入执行权限
- 文件不存在,会报错
- 分发系统还有一个重要的关键是,确保同步的机器的密码一致,否则将不能实现同步;所以这就存在一个弊端,一旦脚本暴露,将会让别人知道如何登陆你机器;当然也有对应的解决办法,那就是使用密钥认证,这样的话,自然在命令行业省去“输入密码< password:" { send "$passwdr" } >''”和“定义密码< set passwd "123123a" >”的命令了
20.34 批量远程执行命令
- 怎么去构建批量执行命令的脚本
[root@aming-01 sbin]# vim exe.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
"}
"password:" { send "$passwd
" }
}
expect "]"
send "$cm
"
expect "]"
send "exit
"
~
~
~
~
~
~
~
~
~
~
:wq
[root@aming-01 sbin]# chmod a+x exe.expect
- 还需要定义一个exe的 for 循环脚本
[root@aming-01 sbin]# vi exe.sh
#!bin/bash
for ip in cat /tmp/ip.list
do
./exe.expect $ip "hostname"
done
~
:wq
- 下面执行下脚本
[root@aming-01 sbin]# vi exe.sh
[root@aming-01 sbin]# sh exe.sh
spawn ssh root@192.168.202.132
root@192.168.202.132's password:
Last failed login: Wed Nov 29 22:26:14 CST 2017 from 192.168.202.130 on ssh:notty
There were 2 failed login attempts since the last successful login.
Last login: Wed Nov 29 22:19:14 2017 from 192.168.202.130
[root@aming-02 ~]# hostname
aming-02
[root@aming-02 ~]# spawn ssh root@127.0.0.1
root@127.0.0.1's password:
Last failed login: Wed Nov 29 22:58:00 CST 2017 from localhost on ssh:notty
There were 2 failed login attempts since the last successful login.
Last login: Wed Nov 29 19:52:21 2017 from 192.168.202.1
[root@aming-01 ~]# hostname
aming-01
[root@aming-01 ~]# [root@aming-01 sbin]#
- 可以看下文件内容
[root@aming-01 sbin]# cat exe.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
"}
"password:" { send "$passwd
" }
}
expect "]"
send "$cm
"
expect "]"
send "exit
"