标签: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 脚本 自动化登陆 远程执行命令
原文地址:http://maomaochong.blog.51cto.com/9260445/1690753