shell-6 expect

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:允许用户交互

猜你喜欢

转载自blog.csdn.net/chunyang315/article/details/80101647