设为首页 收藏本站
查看: 1373|回复: 0

第 三 十 二 天:shell 编 程 之 分 发 系 统 (expect)

[复制链接]
发表于 2018-8-28 13:41:38 | 显示全部楼层 |阅读模式
  小Q:所谓爱国心,是指你身为这个国家的国民,对于这个国家,应当比对其他
  一切的国家感情更深厚。                              —— 萧伯纳
  =======================================================================
  一:前言
  如今一些比较大的企业,大都使用了负载均衡,而有时因为一些程序要更改,或者有些bug
  要修改,如果仅是几台机子的话,我们把已经改好的程序拷过去,或者rsync远程推送一
  下,或者网上NFS共享一下就可以了;但如果有几十台几百台,那样的方法会太繁琐,我
  们此时就可以用expect来批量实现分发任务;
  Expect:一个实现自动交互功能的软件套件,基于Tcl的一种脚本语言,具有简单的语法;
  功 能 :实现自动登录远程机器,并自动执行命令;
  和shell脚本结合,可以实现完全自动化;
  注 意 :使用不带密码的密钥验证也可以实现该功能;没有密钥就只能用对方账号和密码了
  安 装 :yum  install -y excpet
  二:用法
  1. #!/usr/bin/expect
  提示操作系统脚本内的东西是用哪个shell执行的,而expect和bash·win的cmd差不多;
  注意:这一行需要在脚本的第一行。
  2. set command
  用来设置某些变量,或者超时时间的等;比如set user "root"  设置user代表root
  或者set timeout 30 30秒后断开连接 ;set timeout -l 代表永不超时
  3. spawn  将执行的命令或脚本
  spawn是进入expect环境后才可以执行的expect内部命令,若没有装expect或者直接在
  默认的SHELL下执行是无法使用的,找不到他在哪;常用的用法如下:
  spawn ssh -l username 192.168.1.1           远程登录这个终端
  spawn rsync -av root@192.168.1.1:/tmp/1 /tmp/  将远程文件同步过来
  它主要的功能是给ssh运行进程加个壳,用来传递交互指令。
  4. expect "password:"
  也是一个内部命令,他和shell内部命令是一样的;意思是判断上次输出结果里是否
  包含“password:”的字符串,包含则立即返回,否则根据设置的时间等待;
  5. send "command"
  执行交互动作,即登录远程机需执行的命令;常用的有:
  send "yes\r"   输入yes,\r表示回车
  assword:" { send "mima\r" } 表示碰到结尾是assword字样的,输入mima后回车
  6. interact
  执行完成后保持交互状态,然后手动输入命令,类似于su;若没有这一句登录完成后
  会退出,而不是留在远程终端上;用在登录命令后,结尾
  7. $argv 参数数组
  expect脚本可以接受从bash传递过来的参数.可以使用[lindex $argv n]获得;比如:
  set passwd [lindex $argv 0]    就可以在下面用$passwd调用
  spawn ssh root@1.1.1.1  $passwd   当执行时在后面输入密码,比密码放在文件安全
  8. expect eof
  标示子进程已结束的标示符;如果没有eof,可能在子进程没有结束前就退出,或是执
  行完进程后待在远程终端不退出来了;
  三:简单举例 (假设都是用当前目录下的1.expect脚本)
  1.自动远程登录,并执行命令,登录后不退出
#! /usr/bin/expect  

  
set host "192.168.1.1"                       #远程终端的IP
  
set passwd "123456"                          #远程终端root密码
  

  
spawn ssh  root@$host                        #登录远程
  

  
expect {                                     #子进程
  
"yes/no" { send "yes\r"; exp_continue}       #登录后遇到yes/no字样,输入yes回车
  
"assword:" { send "$passwd\r" }              #遇到assword字样,输入变量,回车
  
}                                  ##continue继续执行进程内命令;不结束进程,类似于c中的
  
interact                                     #保持交互,不退出
  登陆后,执行命令然后退出的脚本:
#!/usr/bin/expect                          #固定用法  
set user "root"                            #同上
  
set passwd "123456"
  

  
spawn ssh $user@192.168.11.18              #登录远程,没有吧IP定义为变量,效果一样
  

  
expect {
  
"yes/no" { send "yes\r"; exp_continue}
  
"password:" { send "$passwd\r" }
  
}
  
                                           #登录后执行下面命令
  
expect "]*"                                #代表]#或]$,有的系统root也用]$
  
send "touch /tmp/12.txt\r"                 #碰到]*,创建文件,回车
  
expect "]*"
  
send "echo 1212 > /tmp/12.txt\r"           #重定向,回车
  
expect "]*"
  
send "exit\r"                              #退出系统
  执行脚本: ./1.expect       >>>   回车
  2. 传递参数
#!/usr/bin/expect  
set user  [lindex $argv 0]              #定义参数数组变量
  
set host   "192.168.1.1"
  
set passwd  [lindex $argv 1]            #在bash环境下,即命令行输入,有效保护了密码
  
set cm [lindex $argv 2]                 #定义了一个命令变量,远程机操作的
  

  
spawn ssh $user@$host
  

  
expect {
  
"yes/no" { send "yes\r"}
  
"password:" { send "$passwd\r" }
  
}
  
expect "]*"
  
send "$cm\r"                             #上面定义的变量,也是要在本地bash环境输入
  
expect "]*"
  
send "exit\r"
  执行脚本: ./1.expect  root 密码  w
  注意:数组参数的数字指代的是执行脚本输入的顺序
  3. 自动同步文件
#!/usr/bin/expect  
set passwd "123456"
  

  
spawn rsync -av root@192.168.11.18:/tmp/12.txt /tmp/      #rsync进行的推送
  

  
expect {
  
"yes/no" { send "yes\r"}
  
"password:" { send "$passwd\r" }
  
}
  
expect eof                                                #子进程结束,返回本地终端
  执行脚本: ./1.expect
  4. 指定host和要同步的文件
#!/usr/bin/expect  
set passwd "123456"
  
set host [lindex $argv 1]                     #定义数组参数,第2位输入,为了理解顺序
  
set file [lindex $argv 0]
  

  
spawn rsync -av $file root@$host:$file        #推送到远程
  
expect {
  
"yes/no" { send "yes\r"}
  
"password:" { send "$passwd\r" }
  
}
  
expect eof
  执行脚本: ./1.expect /tmp/12.txt  192.168.11.18
  四:应用实例
  需求:公司网站界面需要更改,更改好的程序给你了,把它分发到那几百台服务器?
  思路:准备个模板机,所有服务器IP写进一个文件供调用,写个shell逐个调用IP,将调用
  的IP给expect实现分发,可以用别的方法实现密码同步,先不说他了;
  核心:rsync -av --files-from=list.txt  /  root@host:/
  1.文件分发系统的实现
#!/usr/bin/expect                  #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\r"}
  
"password:" { send "$passwd\r" }
  
}
  
expect eof
#!/bin/bash                       #shell脚本,设为1.sh  
for ip in `cat ip.list`           #for循环
  
do
  
    echo $ip                      #逐个打印出来供expect调用
  
    ./1.expect $ip list.txt   #执行expect脚本,IP和文件对应上边的顺序
  
done
                                  #IP列表文件,设为list.txt  
192.168.11.18
  
192.168.11.19
  
......
  此时只需执行shell脚本,就可以了;
  
  2. 命令批量执行脚本
#!/usr/bin/expect                #expect脚本,供shell脚本调用  

  
set host [lindex $argv 0]
  
set passwd "123456"
  
set cm [lindex $argv 1]
  

  
spawn ssh root@$host
  

  
expect {
  
"yes/no" { send "yes\r"}
  
"password:" { send "$passwd\r" }
  
}
  
expect "]*"
  
send "$cm\r"
  
expect "]*"
  
send "exit\r"
#!/bin/bash                       #shell脚本,设为1.sh  

  
for ip in `cat ip.list`           #仍然借用了上面的IP列表文件
  
do
  
    echo $ip
  
    ./1.expect $ip 'w;free -m;ls /tmp"  #引号内命令对应$1,cm,如果语句够多,也可以写个
  
done                                    #脚本调用,
  执行只需要执行shell脚本就可以了;
  ===============================================================================
  其实上面的这些批量操作,都是基于各个机子密码一样的情况下,不然就做不到批量了;
  或者我们在生成一个密码列表文件,引入i,将IP和密码顺序一一对应,不过也是一个不小
  的思路;另外我们可以给所有服务器开始的时候设一个相同的密码,但是安全性不高哈,
  我们可以调用expect脚本,两天更改一个密码啊,用我们以前的的mkpasswd;
DSC0000.jpg

DSC0001.jpg




运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.iyunv.com/thread-557804-1-1.html 上篇帖子: 第 三 十 二 天:shell 编 程 之 告 警 系 统 下篇帖子: shell脚本编程:bash shell中的条件判断
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表