expect的安装

expect是在tcl的基础上发展起来的,所以在安装expect之前要先安装tcl。

tcl安装

wget http://nchc.dl.sourceforge.net/sourceforge/tcl/tcl8.4.11-src.tar.gz
tar -zxf tcl8.4.11-src.tar.gz
cd tcl8.4.11/unix
./configure --prefix=/usr/tcl --enable-shared
make
make install
cp tclUnixPort.h ../generic/

注意:
1、安装完毕以后,进入tcl源代码的根目录,把子目录unix下面的tclUnixPort.h copy到子目录generic中。

2、暂时不要删除tcl源代码,因为expect的安装过程还需要用。

安装expect(需tcl的库)

wget https://sourceforge.net/projects/expect/files/Expect/5.45.4/expect5.45.4.tar.gz/download --no-check-certificate -O expect5.45.4.tar.gz
tar -zxf expect5.45.4.tar.gz
cd expect5.45.4
./configure --prefix=/usr/expect --with-tcl=/usr/tcl/lib --with-tclinclude=../tcl8.4.11/generic
make
make install
ln -s /usr/tcl/bin/expect /usr/expect/bin/expect
ln -s /usr/tcl/bin/expect /usr/bin/expect

最简单的安装办法

 yum list expect --showduplicates
 yum install -y expect[-5.45-14.el7_1].x86_64
 
 # 也可以先下载rpm包,然后安装
 yum list expect
 yum install --downloadonly --downloaddir ./  expect[-5.45-14.el7_1].x86_64
 yum install -y ./*.rpm

expect的使用

示例:

#!/bin/bash

/usr/bin/expect <<-EOF
spawn ssh root@node
expect {
"connecting (yes/no)?" {exp_send "yes\r"; exp_continue}
"password:" {exp_send "root\r"}
}
expect "#"
send "hostname\r"
send "echo \\\$HOSTNAME\r"
send "exit\r"
expect eof
EOF
echo "echo $HOSTNAME"

结果:
在这里插入图片描述

视频教程:https://www.bilibili.com/video/BV1cV411r7jW?p=37
推荐阅读:
https://www.jianshu.com/p/32de653aa05ahttps://blog.csdn.net/yifan850399167/article/details/80845031
https://blog.csdn.net/u013163551/article/details/117977204?utm_medium=distribute.pc_5.no_search_link&
https://www.cnblogs.com/lixigang/articles/4849527.html

expect简单用法

#!/usr/bin/expect -f
set timeout 60      #设置超时时间
log_file test.log   #设置脚本日志
log_user 1                   #是否显示脚本输出信息 1代表显示,0代表不显示
set hostname [lindex argv 0] #接收第一个参数
set password [lindex argv 1]
spawn ssh root@$hostname     #连接远程机器
expect {
       "(yes/no)"               
       {
       send "yes\r"
       expect "*password:" {send "$password\r"}
       }
       "*password"
       {
       send "$password\r"
       }
}
send "echo ==\$(rpm -qa | grep mariadb)==\r"
expect -re "==.*==.*==(.*)=="
set mariadb $expect_out(1,string)
expect "*]#"
send "rpm -e --nodeps $mariadb\r"
expect "*]#"
send "exit\r"
expect eof

上述代码即为一个简单的expect脚本,登录到远程机器并卸载mariadb,expect中最常用的就是”expect”和“send”命令。
expect “pattern”
send “command\r”
当远程机出现了匹配”pattern”的字符串,就执行”command”命令,在执行完命令之后别忘了加上回车符,如此便可实现自动输入密码等一系列功能。

shell嵌套expect

#!/bin/bash
hostname=$1                #接收第一个参数
password=$2
/usr/bin/expect <<-EOF    # 重定向到expect
spawn ssh root@${hostname}
expect {
        "(yes/no)"
        {
        send "yes\r"
        expect "*assword:" {send "$password\r"}
        }
        "*assword"
        {
        send "$password\r"
        }
}
expect "*]#"
send "echo 'export MAVEN_HOME=/usr/local/maven' >> /etc/profile\r"
send "echo 'export M2_HOME=\\\$MAVEN_HOME' >> /etc/profile\r"
send "echo 'export PATH=\\\$PATH:\\\$MAVEN_HOME/bin' >> /etc/profile\r"
expect "*]#"
send "source /etc/profile\r"
expect "*]#"
send "exit\r"
expect eof
EOF               #结束重定向

expect常见问题

1、expect脚本中source命令不起作用?

​ shell脚本中嵌套expect脚本,再编写source命令即可正常使用

2、shell嵌套expect脚本中$expect_out(1,string)无法获得匹配字符串?

​ 单纯使用expect脚本即可正常获取

3、shell嵌套expect脚本中对字符转义需要三个反斜杠,expect脚本中对字符转义只需要一个反斜杠。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐