zoukankan      html  css  js  c++  java
  • 2018-08-01 第三十三课

    第三十三课 shell编程(三)

    目录

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


    二十三、 分发系统介绍

    由于业务迭代更新,经常需要更改代码,如果机器很多,此时为了快速更新代码就可以使用分发系统,把更新的代码分别发布到机器上去。其中开源的上线代码的软件有很多,如git等等。这里我们使用shell来编写一个分发系统来上线代码。核心使用expect脚本语言,它可以实现远程执行命令,远程传输数据等操作。

    准备工作

    1.准备1台模版机器,里面是包含有最新的代码

    2.每台分发机器的IP地址和密码

    3.分发系统脚本

    由于分发系统的核心是使用expect,因此先实践几个例子来熟悉expect的语法命令


    二十四、 expect脚本远程登录

    实例1.自动远程登录

    expect分发主机: expect-server 192.168.1.37
    expect远程主机: expect-client 192.168.1.38

    1.在expect分发主机上安装expect

    [root@expect-server ~]# yum -y install expect
    

    2.编辑脚本

    [root@expect-server ~]# vim /usr/local/sbin/expect1.exp
    //添加如下内容
    #!/usr/bin/expect
    #定义变量
    set host "192.168.1.38"
    set passwd "Aa123456"
    #执行命令
    spawn ssh root@$host
    #与远程机器交互 截取特定信息 发送变量
    expect {
    "yes/no" { send "yes
    ";exp_continue }
    "password:" { send "$passwd
    " }
    }
    interact
    
    // set 定义变量
    // spawn 执行命令
    // expect 使用expect语句进行交互
    // 
    表示回车
    // exp_contunue表示继续
    // interact表示继续交互
    // expect eof表示停留远程机器上一会儿再退出
    
    //为了让远程登录时候出现提示,可以清空/root/.ssh/known_hosts目录
    [root@expect-server ~]# > ~/.ssh/known_hosts
    

    3.验证

    //添加执行权限
    [root@expect-server ~]# chmod +x /usr/local/sbin/expect1.exp 
    //执行脚本
    [root@expect-server ~]# /usr/local/sbin/expect1.exp          
    spawn ssh root@192.168.1.38
    The authenticity of host '192.168.1.38 (192.168.1.38)' can't be established.
    ECDSA key fingerprint is SHA256:dpBcqagKb3dleICUyCflHVb7zukCI3ViTczb9LroVU4.
    ECDSA key fingerprint is MD5:7a:2c:c5:0a:02:fc:05:f1:8c:9a:26:f6:8b:7c:76:09.
    Are you sure you want to continue connecting (yes/no)? yes
    Warning: Permanently added '192.168.1.38' (ECDSA) to the list of known hosts.
    root@192.168.1.38's password: 
    Last login: Fri Aug  3 00:43:44 2018 from 192.168.1.9
    //成功实现远程登录
    

    二十五、 expect脚本远程执行命令

    实例2.自动远程登录,并执行命令并退出

    1.编辑脚本

    [root@expect-server ~]# vim /usr/local/sbin/expect2.exp
    //添加如下内容
    #!/usr/bin/expect
    set user "root"
    set host "192.168.1.38"
    set passwd "Aa123456"
    spawn ssh $user@$host
    expect {
    "yes/no" {send "yes
    ";exp_continue}
    "password:" {send "$passwd
    "}
    }
    expect "]*"
    send "touch /tmp/test.aa
    "
    expect "]*"
    send "echo 111 >/tmp/test.aa
    "
    expect "]*"
    send "exit
    "
    

    2.验证

    [root@expect-server ~]# chmod +x !$
    chmod +x /usr/local/sbin/expect2.exp
    [root@expect-server ~]# /usr/local/sbin/expect2.exp
    spawn ssh root@192.168.1.38
    root@192.168.1.38's password: 
    Last login: Fri Aug  3 01:01:07 2018 from 192.168.1.37
    [root@expect-client ~]# touch /tmp/test.aa
    [root@expect-client ~]# echo 111 >/tmp/test.aa
    [root@expect-client ~]# [root@expect-server ~]# 
    
    [root@expect-server ~]# /usr/local/sbin/expect1.exp
    spawn ssh root@192.168.1.38
    root@192.168.1.38's password: 
    Last login: Fri Aug  3 01:10:41 2018 from 192.168.1.37
    [root@expect-client ~]# cat /tmp/test.aa 
    111
    [root@expect-client ~]# 
    

    二十六、 expect脚本传递参数

    实例3.远程传递参数

    1.编辑脚本

    [root@expect-server ~]# vim /usr/local/sbin/expect3.exp
    //添加如下内容
    #!/usr/bin/expect
    set user [lindex $argv 0]
    set host [lindex $argv 1]
    set passwd "Aa123456"
    set cmd [lindex $argv 2]
    spawn ssh $user@$host
    expect {
    "yes/no" {send "yes
    "}
    "password:" {send "$passwd
    "}
    }
    expect "]*"
    send "$cmd
    "
    expect "]*"
    send "exit
    "
    

    2.测试

    [root@expect-server ~]# chmod +x !$
    chmod +x /usr/local/sbin/expect3.exp
    [root@expect-server ~]# /usr/local/sbin/expect3.exp root 192.168.1.38 "ls;w"
    spawn ssh root@192.168.1.38
    root@192.168.1.38's password: 
    Last login: Fri Aug  3 01:11:41 2018 from 192.168.1.37
    [root@expect-client ~]# ls;w
    anaconda-ks.cfg  original-ks.cfg
     01:16:30 up 39 min,  3 users,  load average: 0.00, 0.01, 0.02
    USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
    root     pts/0    192.168.1.9      00:43    9:34   0.12s  0.10s ssh 192.168.1.37
    root     pts/1    192.168.1.37     01:01    9:34   0.06s  0.06s -bash
    root     pts/2    192.168.1.37     01:16    0.00s  0.01s  0.00s w
    [root@expect-client ~]# [root@expect-server ~]# 
    
    //当要输入参数里面有多个命令是需要用""双引号括起来并使用;分号分开
    
    
    //可以在命令行的后面增加set timeout 来指定命令的超时时间 -1为永远
    #!/usr/bin/expect
    set user [lindex $argv 0]
    set host [lindex $argv 1]
    set passwd "Aa123456"
    set cmd [lindex $argv 2]
    spawn ssh $user@$host
    expect {
    "yes/no" {send "yes
    "}
    "password:" {send "$passwd
    "}
    }
    expect "]*"
    send "$cmd
    "
    set timeout -1
    expect "]*"
    send "exit
    "
    
    [root@expect-client ~]# [root@expect-server ~]# /usr/local/sbin/expect3.exp root 192.168.1.38 "vmstat -1"^C
    [root@expect-server ~]# /usr/local/sbin/expect3.exp root 192.168.1.38 "vmstat 1" 
    spawn ssh root@192.168.1.38
    root@192.168.1.38's password: 
    Last login: Fri Aug  3 01:20:14 2018 from 192.168.1.37
    [root@expect-client ~]# 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 780968   2076 120952    0    0    38     5   70   87  0  0 100  0  0
     0  0      0 780968   2076 120936    0    0     0     0   51   53  0  0 100  0  0
     0  0      0 780968   2076 120936    0    0     0     0   50   43  0  0 100  0  0
     0  0      0 780968   2076 120936    0    0     0    24   40   39  0  0 100  0  0
     0  0      0 780968   2076 120936    0    0     0     0   72   74  0  2 98  0  0
    ^C[root@expect-server ~]# 
    //每隔1秒执行一次vmstat命令
    

    二十七、 expect脚本同步文件

    实例4.自动同步文件

    1.编辑脚本

    [root@expect-server ~]# vim /usr/local/sbin/expect4.exp
    //添加如下内容
    #!/usr/bin/expect
    set passwd "Aa123456"
    spawn rsync -av root@192.168.1.38:/tmp/test.aa /tmp/
    expect {
    "yes/no" {send "yes
    "}
    "password:" {send "$passwd
    "}
    }
    expect eof
    
    //如果没有安装rsync,可以用yum -y install rsync安装
    

    2.测试

    //设定执行权限
    [root@expect-server ~]# chmod +x /usr/local/sbin/expect4.exp 
    [root@expect-server ~]# /usr/local/sbin/expect4.exp 
    spawn rsync -av root@192.168.1.38:/tmp/test.aa /tmp/
    root@192.168.1.38's password: 
    receiving incremental file list
    test.aa
    
    sent 30 bytes  received 84 bytes  228.00 bytes/sec
    total size is 4  speedup is 0.04
    //已经把192.168.1.38上的test.aa文件自动同步过来本机了
    

    二十八、 expect脚本指定host和要同步的文件

    实例5.指定host和同步单个文件

    1.编辑脚本

    [root@expect-server ~]# vim /usr/local/sbin/expect5.exp
    //添加如下内容
    !/usr/bin/expect
    set passwd "Aa123456"
    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
    

    2.验证

    [root@expect-server ~]# chmod +x !$
    chmod +x /usr/local/sbin/expect5.exp
    [root@expect-server ~]# /usr/local/sbin/expect5.exp 192.168.1.38 /tmp/test.aa 
    spawn rsync -av /tmp/test.aa root@192.168.1.38:/tmp/test.aa
    root@192.168.1.38's password: 
    sending incremental file list
    test.aa
    
    sent 91 bytes  received 34 bytes  250.00 bytes/sec
    total size is 4  speedup is 0.03
    

    二十九、 构建文件分发系统

    分发系统中首先用expect编写远程同步脚本 并指定文件列表和目标IP列表 然后使用shell脚本调用expect来同步文件。
    这里每台机器必须使用同样的密码才可以同步,也可以让机器之前使用密钥登录。还有让每台机器都安装上rsync
    其核心命令为rsync -av --files-from=list.txt / root@host:/

    1.编辑expect脚本

    [root@expect-server ~]# vim /usr/local/sbin/sync.exp
    //添加如下内容
    #!/usr/bin/expect
    set passwd "Aa123456"
    set host [lindex $argv 0]
    set file [lindex $argv 1]
    #--file-from指定文件列表路径 -R表示同步时目标会级联创建目录
    spawn rsync -avR --files-from=$file / root@$host:/
    expect {
    "yes/no" {send "yes
    "}
    "password:" {send $passwd
    }
    }
    expect eof
    
    [root@expect-server ~]# chmod +x !$
    chmod +x /usr/local/sbin/sync.exp
    
    

    2.创建ip.list 同步机器的IP列表

    [root@expect-server ~]# vim /tmp/ip.txt
    //内容如下
    192.168.1.38
    

    3.创建file.list 需要同步文件的列表

    [root@expect-server ~]# vim /tmp/file.list
    //添加如下内容
    /tmp/test
    /tmp/test.aa
    

    4.创建 rsync.sh 脚本

    [root@expect-server ~]# vim /usr/local/sbin/rsync.sh
    //添加如下内容
    #!/bin/bash
    for i in `cat /tmp/ip.list`
    do
            ./rsync.exp $i /tmp/file.list
    done
    

    5.测试

    [root@expect-server ~]# chmod +x /usr/local/sbin/rsync.sh 
    [root@expect-server ~]# sh +x /usr/local/sbin/rsync.sh  
    spawn rsync -avR --files-from=/tmp/file.list / root@192.168.1.38:/
    root@192.168.1.38's password: 
    building file list ... done
    tmp/
    tmp/test
    
    sent 119 bytes  received 37 bytes  312.00 bytes/sec
    total size is 8  speedup is 0.05
    

    三十、 批量远程执行命令

    当同步完代码后有可能需要批量地重启服务,因此还需要批量远程执行命令,类似于自动化。
    这里是用expect编写执行命令的脚本并用shell脚本来批量调用它。

    1.编辑expect脚本

    [root@expect-server ~]# vim /usr/local/sbin/execute.exp
    //内容如下
    #!/usr/bin/expect
    set passwd "Aa123456"
    set host [lindex $argv 0]
    set cmd [lindex $argv 1]
    spawn ssh root@$host
    expect {
    "yes/no" {send "yes
    "}
    "password:" {send "$passwd
    "}
    }
    expect "]*"
    send "$cmd
    "
    expect "]*"
    send "exit
    "
    

    2.编写shell脚本

    [root@expect-server ~]# vim /usr/local/sbin/execute.sh
    #!/bin/bash
    for i in $(cat /tmp/ip.list)
    do
            echo $i
            /usr/local/sbin/execute.exp $i "systemctl status httpd.service "
    done
    

    3.测试

    [root@expect-server sbin]# chmod +x /usr/local/sbin/execute.exp /usr/local/sbin/execute.sh
    "execute.sh" 6L, 138C written                                                                                                                          
    [root@expect-server sbin]# /usr/local/sbin/execute.sh                                     
    192.168.1.38
    spawn ssh root@192.168.1.38
    root@192.168.1.38's password: 
    Last login: Fri Aug  3 02:40:00 2018 from 192.168.1.37
    [root@expect-client ~]# systemctl status httpd.service 
    ● httpd.service - The Apache HTTP Server
       Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
       Active: active (running) since Fri 2018-08-03 02:40:07 CST; 2min 22s ago
         Docs: man:httpd(8)
               man:apachectl(8)
      Process: 16668 ExecStop=/bin/kill -WINCH ${MAINPID} (code=exited, status=0/SUCCESS)
     Main PID: 16678 (httpd)
       Status: "Total requests: 0; Current requests/sec: 0; Current traffic:   0 B/sec"
       CGroup: /system.slice/httpd.service
               ├─16678 /usr/sbin/httpd -DFOREGROUND
               ├─16679 /usr/sbin/httpd -DFOREGROUND
               ├─16680 /usr/sbin/httpd -DFOREGROUND
               ├─16681 /usr/sbin/httpd -DFOREGROUND
               ├─16682 /usr/sbin/httpd -DFOREGROUND
               └─16683 /usr/sbin/httpd -DFOREGROUND
    
    Aug 03 02:40:01 expect-client systemd[1]: Starting The Apache HTTP Server...
    Aug 03 02:40:07 expect-client httpd[16678]: AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using fe80::20c:29ff:fea7...is message
    Aug 03 02:40:07 expect-client systemd[1]: Started The Apache HTTP Server.
    Hint: Some lines were ellipsized, use -l to show in full.
    

    三十一、 扩展

    shell多线程

    http://blog.lishiming.net/?p=448

    shell习题做一下

    http://www.apelearn.com/study_v2/chapter15.html#shll

  • 相关阅读:
    ubuntu16.04解决播放swf视频文件问题
    ubuntu下设置clion是使用clang和clang++
    Linux 下没有conio.h 已解决
    适合最新版docker自定义启动配置
    nginx限制ip并发数
    nginx 403错误
    ubuntu 支持中文
    CentOS 5 上使用yum同时安装32位和64位包的解决方法
    rhel yum报错
    因为swap分区无法启动
  • 原文地址:https://www.cnblogs.com/minn/p/9411535.html
Copyright © 2011-2022 走看看