美文网首页
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 案例

    Shell编程一 Shell防范ARP攻击 Shell编程二 Shell防范DDos攻击 Shell编程三 ...

  • day28-Shell脚本基础

    SHELL编程基础 三小时光速入门因为集群架构会用到shell编程基础,提前讲一丢丢。 shell编程 1. 为什...

  • BigData~01:Shell

    Shell编程基础 内容大纲 一、Shell编程二、高级文本处理命令:sed、awk、cut三、crontab定时...

  • shell 第一天

    shell编程初识 1.1 shell编程初识 shell的定义 Shell 是命令解释器 Shell 也是...

  • 78.shell编程

    shell编程 Shell脚本,是一种为shell编写的脚本程序。 Shell编程跟JavaScript、Pyth...

  • 2019-01-25

    Linux系统Shell编程指南 前言 适合人群:有类似C编程基础的人 一、Shell编程介绍 Shell解释型语...

  • shell编程(三)

    数组 普通数组 只能以数字作为索引(下标)关联数组 可以使用数字也可以使用字符串作为索引(下标)数组名[索引]...

  • shell编程三

    目录 一、分发系统介绍二、expect脚本远程登录三、expect脚本远程执行命令四、expect脚本传递参数五、...

  • day 28

    shell编程基础 shell编程一小时光速入门web集群架构会用到shell编程基础 1、为什么要学shell编...

  • Shell 编程的 Hello World

    什么是 Shell?简单来说,Shell 编程是对 Linux 命令的逻辑化处理。 来看看 Shell 编程是如何...

网友评论

      本文标题:shell编程三

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