三十三节课笔记

 20.27 分发系统介绍
20.28 expect脚本远程登录
20.29 expect脚本远程执行命令
20.30 expect脚本传递参数
20.31 expect脚本同步文件
20.32 expect脚本指定host和要同步的文件
20.33 构建文件分发系统
20.34 批量远程执行命令

扩展:
shell多线程  http://blog.lishiming.net/?p=448
给你提供一本电子书 链接: http://pan.baidu.com/s/1mg49Taw 密码:yk4b
shell习题做一下  http://www.apelearn.com/study_v2/chapter15.html#shll

 20.27 分发系统介绍

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

准备工作

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

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

3.分发系统脚本

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

 20.28 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\r";exp_continue } "password:" { send "$passwd\r" } } interact // set 定义变量 // spawn 执行命令 // expect 使用expect语句进行交互 // \r表示回车 // 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 //成功实现远程登录

 20.29 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\r";exp_continue} "password:" {send "$passwd\r"} } expect "]*" send "touch /tmp/test.aa\r" expect "]*" send "echo 111 >/tmp/test.aa\r" expect "]*" send "exit\r"

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 ~]# 

20.30 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\r"} "password:" {send "$passwd\r"} } expect "]*" send "$cmd\r" expect "]*" send "exit\r"

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\r"} "password:" {send "$passwd\r"} } expect "]*" send "$cmd\r" set timeout -1 expect "]*" send "exit\r" [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命令

20.31 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\r"} "password:" {send "$passwd\r"} } 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文件自动同步过来本机了

20.32 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\r"} "password:" {send "$passwd\r"} } 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

20.33 构建文件分发系统

分发系统中首先用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\r"} "password:" {send $passwd\r} } 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

20.34 批量远程执行命令

当同步完代码后有可能需要批量地重启服务,因此还需要批量远程执行命令,类似于自动化。
这里是用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\r"} "password:" {send "$passwd\r"} } expect "]*" send "$cmd\r" expect "]*" send "exit\r"

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 [email protected] [email protected]'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.

猜你喜欢

转载自www.cnblogs.com/linuxzhang/p/9860743.html