码迷,mamicode.com
首页 > 系统相关 > 详细

shell 中嵌套expect 详解

时间:2015-09-02 19:13:29      阅读:755      评论:0      收藏:0      [点我收藏+]

标签:shell 嵌套expect     脚本 自动化登陆     远程执行命令

    之前我在写shell脚本中嵌套expect遇到了这样的问题,最后经过研究发现,在expect中的shell命令是需要转换才能生效的。否知错误百出,让人吐血不已。下面我讲解下我所遇到的问题。


    我要实现通过ping检测存活主机。如果存活将这个IP存入root/uphost.txt 这个文件中。并且用expect免输密码登录存活主机。登录存活主机后,检测这个主机上的80是否开启,如果没有开启就开启80。    如果主机不存活。就将这个主机ip存在/root/downhost.txt。  

    现在的问题出在send "netstat -anptl|grep 80 && a=0 || a=1 ; if [ \$a -eq 1 ] ; then /etc/init.d/httpd start ; fi\r"  这个地方。他一直报错我怀疑是转义问题但是,一直没解决。



我的脚本

#!/bin/bash
for i in `seq 121 122`
  do
   ping -c 3 -i 0.2 -w 3 192.168.1.$i >/dev/null
        if [ $? -eq 0 ]
        then
         echo "Host is up 192.168.1.$i" >>/root/uphost.txt
/usr/bin/expect <<-EOF
        set time 30
        spawn ssh -l root 192.168.1.$i
        expect {
        "yes/no" { send "yes/r";exp_continue }
        "*password:" { send "aptech1.\r" }
        }
        expect "*#"
        send "netstat -anptl|grep 80 && a=0 || a=1 ; if [ \$a -eq 1 ] ; then /etc/init.d/httpd start ; fi\r"
        expect "*#"
        send "exit\r"
        expect eof
        EOF
        else
        echo "Host is down 192.168.1.$i" >>/root/downhost.txt
        fi
  done


报错如下:

        技术分享


一直读取不到变量$a我也是醉了。为了排除其他原因我将  send "netstat -anptl|grep 80 && a=0 || a=1 ; if [ \$a -eq 1 ] ; then /etc/init.d/httpd start ; fi\r"换成了send "/etc/init.d/httpd strat \r"


立刻执行成功。说明错误果然是在这条命里中。


经过查阅资料终于将问题解决:

                   

#!/bin/bash
for i in `seq 121 122`
  do
   ping -c 3 -i 0.2 -w 3 192.168.1.$i >/dev/null   
        if [ $? -eq 0 ]
        then
         echo "Host is up 192.168.1.$i" >>/root/uphost.txt
/usr/bin/expect <<-EOF                     expect嵌套到shell中去。这里的“-EOF”必须有“-”
        set time 30
        spawn ssh -l root 192.168.1.$i
        expect {            
        "yes/no" { send "yes/r";exp_continue } exp_continue意思是:执行完这一条执行下一条。
        "*password:" { send "aptech1.\r" } 若此行后面还有要抓取的字段那么就要加exp_continue
        }
        expect "*#"                      *:泛匹配 当命令执行完毕就会开始新的一行当抓取                                                 到“#” [root@localhost ~]#  说明命令执行完毕 


         send "netstat -anptl|grep 80 && result=0 || result=1;if \[ \"$\{result\}\" = 0 \]; then exit 1 ;else /etc/init.d/httpd start ;fi\r"  

                                        result=0 || result=1将前面命令的执行结果状态赋予 0                                            和1 。成功为:0 失败和其它都为1。

        expect "*#"
        send "exit\r"                          命令执行完毕退出远程终端
        expect eof
        EOF                                    到此shell嵌套expect结束。

        else
        echo "Host is down 192.168.1.$i" >>/root/downhost.txt
        fi
  done


注意:这里的重点是 send "netstat -anptl|grep 80 && result=0 || result=1;if \[ \"$\{result\}\" = 0 \]; then exit 1 ;else /etc/init.d/httpd start ;fi\r"  中的 if \[ \"$\{result\}\" = 0 \]的特殊符号转义,如果不注意,你就可能要花很长时间去排查错误。


      还有就是expect中的  “ { ” 和 “ } ” 前后一定要有空格。否则也会报错。


         expect {            
        "yes/no" { send "yes/r";exp_continue } 
        "*password:" { send "aptech1.\r" }   
        }

        

    此次脚本编写终于圆满成功,都说不会shell的运维不是好运维。shell以前一直是我的硬伤,但是经过最近自己写了几个小脚本,有重新温习了shell的基础知识后,发现其实他并没有那么难,最重要是愿意花时间去做,静下心来去看。不知不觉中提升了自我,愿这篇文章能给正在shell中奋斗的挨踢兄弟们提供一点帮助。  

                                                                    

                                                                ---》毛毛

        

 

本文出自 “沙漠骆驼” 博客,请务必保留此出处http://maomaochong.blog.51cto.com/9260445/1690753

shell 中嵌套expect 详解

标签:shell 嵌套expect     脚本 自动化登陆     远程执行命令

原文地址:http://maomaochong.blog.51cto.com/9260445/1690753

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!