zoukankan      html  css  js  c++  java
  • 20.31 expect脚本同步文件 20.32 expect脚本指定host和要同步的文件 20.33 构建文件分发系统 20.34 批量远程执行命令

    • 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 "

  • 相关阅读:
    C#中|(位或)和||(逻辑或)
    VS快捷键(转)
    C# 3.0 新特性 学习(二):匿名类型、扩展方法
    Highcharts 如何添加基准线
    怎样用Diskpart进行分区
    命名空间别名限定符 (::)
    NDK下 将Platinum SDK 编译成so库 (android upnp)
    在native线程利用JNI 反射自定义类
    GithubClient(ANDROID)开源之旅(一) 初探GitHub
    基于Platinum库的DMR实现(android)
  • 原文地址:https://www.cnblogs.com/pta188/p/9341838.html
Copyright © 2011-2022 走看看