美文网首页
shell编程三

shell编程三

作者: XiaoMing丶 | 来源:发表于2019-01-16 22:29 被阅读0次

    目录

    一、分发系统介绍
    二、expect脚本远程登录
    三、expect脚本远程执行命令
    四、expect脚本传递参数
    五、expect脚本同步文件
    六、expect脚本指定host和要同步的文件
    七、构建文件分发系统
    八、批量远程执行命令

    一、分发系统介绍

    • 场景:
      服务器是LAMP或LNMP环境,运行PHP网站业务。随着业务增长,代码不断迭代,有增加新功能的需求,需要修改代码,但提供服务的机器数量庞大,逐一更新服务器上的代码比较困难。

    • 分发系统介绍
      分发系统的作用是将每段时间更新的代码分别发到服务机器上去,这里使用shell编程脚本实现代码上线(将代码发布到线上环境)。部分开源软件系统也可以实现发布代码到服务器的功能。

    • 上线准备工作及过程
      准备一台模板机器,该机器上的代码是更新后需要上线的代码,使用expect脚本,借助rsync将更新的代码推送到需要上线的机器上。如果需要执行一些命令,可以借助expect登录机器执行命令。

    二、expect脚本远程登录

    expect是一种能够按照脚本内容里面设定的方式与交互式程序进行“会话”的程序。expect可以知道程序会提示或反馈什么内容以及什么是正确的应答。它是一种可以提供“分支和嵌套结构”来引导程序流程的解释型脚本语言。另外,还可以在随时需要的时候把控制权交给用户,然后再还给脚本。

    • 安装expect
    #若未安装则使用yum安装
    [root@minglinux-01 ~] yum install -y expect
    
    • expect实现远程登录脚本
    [root@minglinux-01 /usr/local/sbin] vim 1.expect
    
      1 #!/usr/bin/expect   
      2 set host "192.168.162.132"   #set 变量名 定义变量
      3 set passwd "123456"   #
      4 spawn ssh root@$host  #
      5 expect {   #用户交互
      6 "yes/no"{ send "yes\r";exp_continue }  #截取输出内容,当输出的内容包含yes/no时,发送yes并回车(初次登录时的情景),\r表示回车,exp_continue表示继续
      7 "password: " { send "$passwd\r" }  #继续发送密码
      8 }
      9 interact #Interact表示停留在远程机器上等待交互不退出
    #expect eof则会在远程机器上停留一两秒后再退出
    #不加第九行interact会马上退出远程机器
    
    • 测试expect脚本
    [root@minglinux-01 /usr/local/sbin] chmod a+x 1.expect  #增加权限
    #清除内容恢复"yes/no"提示
    [root@minglinux-01 /usr/local/sbin] vim /root/.ssh/known_hosts   
    [root@minglinux-01 /usr/local/sbin] ./1.expect 
    spawn ssh root@192.168.162.132
    The authenticity of host '192.168.162.132 (192.168.162.132)' can't be established.
    ECDSA key fingerprint is SHA256:iqL2TD9uuoPLw0iBc4CDeg2rwceB4m5w79eFoE94zWo.
    ECDSA key fingerprint is MD5:5b:95:6c:f7:1b:4d:84:5e:66:0d:b1:fa:a7:e2:4e:d6.
    Are you sure you want to continue connecting (yes/no)? yes
    Warning: Permanently added '192.168.162.132' (ECDSA) to the list of known hosts.
    root@192.168.162.132's password: 
    Last login: Mon Jan 14 17:16:31 2019 from 192.168.162.130
    [root@minglinux-02 ~]
    

    三、expect脚本远程执行命令

    #minglinux-01上执行
    [root@minglinux-01 /usr/local/sbin] vim 2.expect
    
      1 #!/usr/bin/expect
      2 set user "root"
      3 set passwd "123456"
      4 spawn ssh $user@192.168.162.132
      5 
      6 expect {
      7 "yes/no" { send "yes\r"; exp_continue}
      8 "password:" { send "$passwd\r" }
      9 }
     10 expect "]*"  #当匹配到"]*"字符时执行以下命令,"*"表通配
     11 send "touch /tmp/expect.txt\r"
     12 expect "]*"
     13 send "echo hellohello > /tmp/expect.txt\r"
     14 expect "]*"
     15 send "exit\r"  #直接退出远程机器
    
    [root@minglinux-01 /usr/local/sbin] chmod a+x 2.expect 
    [root@minglinux-01 /usr/local/sbin] ./2.expect 
    spawn ssh root@192.168.162.132
    root@192.168.162.132's password: 
    Last login: Mon Jan 14 21:39:24 2019 from 192.168.162.1
    [root@minglinux-02 ~] touch /tmp/expect.txt
    [root@minglinux-02 ~] echo hellohello > /tmp/expect.txt
    
    ##minglinux-02上执行
    [root@minglinux-02 /tmp] cat expect.txt 
    hellohello
    

    四、expect脚本传递参数

    [root@minglinux-01 /usr/local/sbin] vim 3.expect
    
      1 #!/usr/bin/expect
      2 
      3 set user [lindex $argv 0] #将第一个参数传递给变量user
      4 set host [lindex $argv 1] #将第二个参数传递给变量host
      5 set passwd "123456"
      6 set cm [lindex $argv 2] #将第三个变量传递给cm
      7 spawn ssh $user@$host
      8 
      9 expect { 
     10 "yes/no" { send "yes\r"}
     11 "password:" { send "$passwd\r" }
     12 }
     13 expect "]*"
     14 send "$cm\r"
     15 expect "]*"
     16 send "exit\r"
    
    #执行3.expect
    [root@minglinux-01 /usr/local/sbin] chmod a+x 3.expect 
    [root@minglinux-01 /usr/local/sbin] ./3.expect root 192.168.162.132 ls
    spawn ssh root@192.168.162.132
    root@192.168.162.132's password: 
    Last login: Mon Jan 14 22:02:12 2019 from 192.168.162.130
    [root@minglinux-02 ~] ls
    anaconda-ks.cfg             SIMLI.TTF
    a.txt                       zabbix-release-3.2-1.el7.noarch.rpm
    jdk-8u191-linux-x64.tar.gz
    #执行多个命令
    [root@minglinux-01 /usr/local/sbin] ./3.expect root 192.168.162.132 "ls;w;vmstat 1"
    spawn ssh root@192.168.162.132
    root@192.168.162.132's password: 
    Last login: Mon Jan 14 22:25:19 2019 from 192.168.162.130
    [root@minglinux-02 ~] ls;w;vmstat 1
    anaconda-ks.cfg             SIMLI.TTF
    a.txt                       zabbix-release-3.2-1.el7.noarch.rpm
    jdk-8u191-linux-x64.tar.gz
     22:28:07 up 1 day, 18:09,  4 users,  load average: 0.00, 0.01, 0.05
    USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
    root     pts/0    192.168.162.1    15:58    5:20m  0.03s  0.03s -bash
    root     pts/1    192.168.162.1    21:39   21:11   0.04s  0.04s -bash
    root     pts/2    192.168.162.130  17:19    5:09m  0.02s  0.02s -bash
    root     pts/3    192.168.162.130  22:28    0.00s  0.02s  0.02s w
    procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
     r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
     1  0      0 592460   2076 664988    0    0     1    11   52   54  0  0 100  0  0
     0  0      0 592528   2076 665060    0    0     0     0   99   93  0  0 100  0  0
     0  0      0 592528   2076 665060    0    0     0     0   88   84  0  0 100  0  0
     0  0      0 592528   2076 665060    0    0     0     0  119  111  0  0 100  0  0
     0  0      0 592528   2076 665060    0    0     0     0   99   91  0  0 100  0  0
     0  0      0 592528   2076 665060    0    0     0     0   98   88  0  1 100  0  0
     0  0      0 592528   2076 665060    0    0     0     0  113   99  0  0 100  0  0
     0  0      0 592528   2076 665060    0    0     0     0   98   93  0  1 100  0  0
    procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
     r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
     1  0      0 592528   2076 665060    0    0     0     0   89   83  0  0 100  0  0
     0  0      0 592528   2076 665060    0    0     0     0  100   96  0  0 100  0  0
    ##在expect中存在超时时间(大约10s),不适合运行需要长时间执行的命令如vmstat
    

    五、expect脚本同步文件

    [root@minglinux-01 /usr/local/sbin] vim 4.expect
    
      1 #!/usr/bin/expect
      2 set passwd "123456"
      3 spawn rsync -av root@192.168.162.132:/tmp/expect.txt /tmp/
      4 expect {
      5 "yes/no" { send "yes\r"}
      6 "password:" { send "$passwd\r" }
      7 }
      8 expect eof #若无expect eof则rsync还未来得及传输文件就被退出终端
    #使用set timeout设置超时时间,
    #如set timeout 5设置超时时间为5s,
    #set timeout -1设置超时时间为永不超时。
     
    
    [root@minglinux-01 /usr/local/sbin] chmod a+x 4.expect
    [root@minglinux-01 /usr/local/sbin] ./4.expect 
    spawn rsync -av root@192.168.162.132:/tmp/expect.txt /tmp/
    root@192.168.162.132's password: 
    receiving incremental file list
    expect.txt
    
    sent 43 bytes  received 106 bytes  99.33 bytes/sec
    total size is 11  speedup is 0.07
    [root@minglinux-01 /usr/local/sbin] ls /tmp/expect.txt 
    /tmp/expect.txt
    

    六、expect脚本指定host和要同步的文件

    #从本机同步到对方
    [root@minglinux-01 /usr/local/sbin] vim 5.expect
    #脚本内容,此方式只能同步一个文件或者目录
      1 #!/usr/bin/expect
      2 set passwd "123456"
      3 set host [lindex $argv 0]
      4 set file [lindex $argv 1]
      5 spawn rsync -av $file root@$host:$file
      6 expect {
      7 "yes/no" { send "yes\r"}
      8 "password:" { send "$passwd\r" }
      9 }
     10 expect eof
    
    [root@minglinux-01 /usr/local/sbin] chmod a+x 5.expect 
    [root@minglinux-01 /usr/local/sbin] ./5.expect 192.168.162.132 "/tmp/expect.txt"
    spawn rsync -av /tmp/expect.txt root@192.168.162.132:/tmp/expect.txt
    root@192.168.162.132's password: 
    sending incremental file list
    
    sent 48 bytes  received 12 bytes  120.00 bytes/sec
    total size is 11  speedup is 0.18
    

    七、构建文件分发系统

    • 需求背景:
      对于大公司而言,肯定时不时会有网站或者配置文件更新,而且使用的机器肯定也是好多台,少则几台,多则几十甚至上百台。所以,自动同步文件是至关重要的。
    • 思路:
      需要有一台模板机器,准备好要分发的文件,使用expect脚本批量将需要同步的文件分发到目标机器。
    • 核心命令:
      rsync -av –files-from=list.txt / root@host:/
    #用于同步文件的rsync.expect 脚本文件内容
    [root@minglinux-01 /usr/local/sbin] vim rsync.expect
    
      1 #!/usr/bin/expect
      2 set passwd "123456"  #考虑安全性可使用密钥认证
      3 set host [lindex $argv 0]
      4 set file [lindex $argv 1]
      5 spawn rsync -avR --files-from=$file / root@$host:/ #加R参数,此时若目标机器不存在同步的目录时会自动创建级联目录
      6 expect {
      7 "yes/no" { send "yes\r"}
      8 "password:" { send "$passwd\r" }
      9 }
     10 expect eof
    
    #创建文件路径的列表文件
    [root@minglinux-01 /usr/local/sbin] vim file.list
    
      1 /root/root.txt
      2 /tmp/2018.txt
    #创建相关文件
    [root@minglinux-01 /usr/local/sbin] touch /root.txt
    [root@minglinux-01 /usr/local/sbin] touch /tmp/2018.txt
    
    #创建主机IP列表文件
    [root@minglinux-01 /usr/local/sbin] vim ip.list
    
      1 192.168.162.132
    
    #创建用于遍历ip列表的脚本rsync.sh
    [root@minglinux-01 /usr/local/sbin] vim rsync.sh
    
      1 #!/bin/bash
      1 #!/bin/bash
      2 for ip in `cat ip.list`
      3 do
      4     echo $ip
      5     ./rsync.expect $ip file.list
      6 done
    
    #执行脚本
    [root@minglinux-01 /usr/local/sbin] chmod a+x rsync.expect
    [root@minglinux-01 /usr/local/sbin] chmod a+x rsync.sh
    [root@minglinux-01 /usr/local/sbin] sh rsync.sh 
    192.168.162.132
    spawn rsync -avR --files-from=file.list / root@192.168.162.132:/
    root@192.168.162.132's password: 
    building file list ... done
    root/
    root/root.txt
    tmp/
    tmp/2018.txt
    
    sent 200 bytes  received 60 bytes  173.33 bytes/sec
    total size is 0  speedup is 0.00
    
    #查看目标主机
    [root@minglinux-02 ~] ls /root/root.txt
    /root/root.txt
    [root@minglinux-02 ~] ls /tmp/2018.txt
    /tmp/2018.txt
    

    八、批量远程执行命令

    • 思路:创建一个执行指定命令的expect脚本, 然后使用一个shell脚本来循环执行这个expect脚本

    • 创建exe.expect内容如下

    [root@minglinux-01 /usr/local/sbin] vim exe.expect
    
      1 #!/usr/bin/expect
      2 set host [lindex $argv 0]
      3 set passwd "123456"
      4 set cm [lindex $argv 1]
      5 spawn ssh root@$host
      6 expect {
      7 "yes/no" { send "yes\r"}
      8 "password:" { send "$passwd\r" }
      9 }
     10 expect "]*"
     11 send "$cm\r"
     12 expect "]*"
     13 send "exit\r"
    
    • 创建 exe.sh内容如下
    [root@minglinux-01 /usr/local/sbin] vim exe.sh
    
      1 #!/bin/bash
      2 for ip in `cat ip.list`
      3 do
      4     echo $ip
      5     ./exe.expect $ip "w;free -m;ls /tmp"
      6 done
    
    • 执行脚本
    [root@minglinux-01 /usr/local/sbin] chmod a+x exe.expect 
    [root@minglinux-01 /usr/local/sbin] sh exe.sh 
    192.168.162.132
    spawn ssh root@192.168.162.132
    root@192.168.162.132's password: 
    Last login: Wed Jan 16 22:27:12 2019 from 192.168.162.130
    [root@minglinux-02 ~] w;free -m;ls /tmp
     22:27:32 up 1 day, 22:48,  3 users,  load average: 0.00, 0.01, 0.05
    USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
    root     pts/0    192.168.162.1    22:15   11:57   0.01s  0.01s -bash
    root     pts/1    192.168.162.130  22:27    0.00s  0.00s  0.00s w
    root     pts/3    192.168.162.1    二16   28:31m  0.05s  0.05s -bash
                  total        used        free      shared  buff/cache   available
    Mem:           1821         589         580           9         652        1047
    Swap:          2047           0        2047
    2018.txt
    331601950@qq.com
    expect.txt
    mysql.sock
    systemd-private-6e247fb2b41e4891b7f0ef4e53aae16d-nginx.service-CC0cwz
    vmware-root
    yum_save_tx.2018-12-21.16-22.lJigJq.yumtx
    

    相关文章

      网友评论

          本文标题:shell编程三

          本文链接:https://www.haomeiwen.com/subject/fcafdqtx.html