expect脚本同步文件
- 使用expect可以将一台机器的文件同步到另一台机器中,脚本4.expect如下
#!/usr/bin/expect
set passwd "xxxxxxx"
spawn rsync -av root@192.168.xxx.xxx:/tmp/1.txt /tmp/
expect {
"yes/on" {send "yes\r"}
"passwoed:" {send "$passwd\r"}
expect eof
如果手动执行rsync,是需要手动输入密码的,那么使用脚本就很方便了。
:如果不加expect eof或是interact ,还没开始传输就已经退出了远程登录。它们的作用是给你一些时间让你进行一些操作。
expect脚本指定host和要同步的文件
- expect设置超时时间
#!/usr/bin/expect
set user [lindex $sargv 0]
set host [lindex $sargv 1]
set paswwd "xxxxxx"
set cm [lindex $sargv 2]
spawn ssh $user@$host
expect {
"yes/no" {send "yes\r" }
"password:" {send "$passwd\r"}
}
expect "]*"
send "$cm\r"
set timeout -1 //永久不超时
expect "]*"
send "exit\r"
- 在脚本中即使设置了set timeout -1 ,但是并没有expect eof也是会马上退出。
expect eof是expec的结尾。
exit是一条命令,退出对方的终端。
指定host和要同步的文件 5.expect
#!/usr/bin/expect
set passwd "xxxxxxx"
set host [lindex $argv 0] /参数1
set file [lindex $argv 1] /参数2 ,需要同步的文件,需要写绝对路径
spawn rsync -av $file root@$host:$file
expect {
"yes/no" { send "yes\r}"
"password:" { send "$passwd\r" }
}
expect eof
- 加上执行权限后,执行该命令
./4.expect 192.168.244.xxx "/tmp/1.txt"
适合本地同步到远程,单个文件。
构建文件分发系统
需求背景
对于大公司而言,肯定时不时会有网站或者配置文件更新,而且使用的机器肯定也是很多台,少则几台,多则几十上百台。所以,自动同步文件是很重要的实现思路
首先要有一台模板机器,把要分发的文件写入到一个文件列表中去,使用rsync –files-from=文件列表,就能实现将文件列表中的文件同步到远程中去。文件列表需要使用绝对路径。示例脚本rsync.expect
#!/usr/bin/expect
set passwd "xxxxx"
set host [lindex $argv 0]
set file [lindex $argv 1] //这里file就是指文件列表
spawn rsync -av --files-from=$file / root@$host:/
expect {
"yes/no" { send "yes\r" }
"password:" { send "$passwd\r" }
}
expect eof
- 编写file文件列表 vi /tmp/file.list
/root/123/111/12.txt
/root/shell/1.sh
/tmp/1.txt
·这里的路径需要保证对方机器上也要有,里面的文件是我们才需要同步的,比如/root/shell目录,对方机器上也存在才能同步,或者加-R选项,它会自动创建。
spawn rsync -avR --files-from=$file / root@$host:/
· 需要远程同步的机器不止一台,那么需要ip列表
vi /tmp/ip.txt
192.168.244.xxx
192.168.244.xxx
做expect脚本的前提是机器密码需要是一样的。如果不一样,就只能每台机器定义密码,不足是expect脚本一旦泄露,那里面保存的密码就有可能被人猜到。另一种思路就是做秘钥认证。就不要输入密码,那么”password:” { send “$passwd\r” }可以不要。
- 前面2个都有了,还需要创建rsync.sh
#!/bin/bash
for ip in `cat /tmp/ip.txt`
do
echo $ip
./rsync.expect $ip list.txt //参数1 IP地址 参数2 文件列表
done
目的是遍历这些Ip地址
- 执行前需要个rsync.expect执行权限,才能正常的去执行它
如果需要同步的文件不存在会报错。执行过后就可以在另一台机器上查看到被同步的文件
批量远程执行命令
有了分发系统后,可以传文件了还不够,比如传输文件后需要执行一些命令
批量执行命令脚本exe.expect
#!/usr/bin/expect
set host [lindex $argv 0]
set passwd "xxxxxx"
set cm [lindex $argv 1]
spawn ssh root@$host
expexct {
"yes/no" { send "yes\r" }
"password:" { send "$passwd\r" }
}
expect "]*"
send "$cm\r"
expect "]*"
send "exit\r"
- 需要定义exe.sh脚本
#!/bin/bash
for ip in `cat /tmp/ip.txt`
do
./exe.expect $ip "ip addr" //后面用来指定需要执行的命令
- Expect中最关键的四个命令是send,expect,spawn,interact。
send:用于向进程发送字符串
接收一个字符串参数,并将该参数发送到进程
expect:从进程接收字符串
通常是用来等待一个进程的反馈
单一分支模式语法:
expect "hi" {send "You said hi"}
匹配到hi后,会输出"you said hi"
多分支模式语法:
expect "hi" { send "You said hi\n" } \
"hello" { send "Hello yourself\n" } \
"bye" { send "That was unexpected\n" }
匹配到hi,hello,bye任意一个字符串时,执行相应的输出。等同于如下写法:
expect {
"hi" { send "You said hi\n"}
"hello" { send "Hello yourself\n"}
"bye" { send "That was unexpected\n"}
}
spawn:启动新的进程
spawn后的send和expect命令都是和spawn打开的进程进行交互的
interact:允许用户交互