expect定义及使用场景

expect是一个免费的编程工具,用来实现自动的交互任务。在实际工作中,在linux运行linux命令、脚本或程序时,这些输入有时会需要人工手进行,而利用expect,可以根据程序的提示,模拟标注输入提供给程序,从而实现自动化交互。

expect安装

配置好对应的yum源之后,执行命令:

yum install -y expect

安装成功之后,可以在命令行执行命令检验:​​expect -div​

expect常用的四个命令

  • send
    接收一个字符串参数,并将参数发送到进程。示例如下:​​​send "yes\n"​​ 输入一个yes并换行。
  • expect
    通常用来等待一个进程的反馈,根据进程的反馈,再发送对应的交互式命令:​​​expect "*assword:" { send "123456\n"}​​当出现的响应信息带有assword:,通过send命令传入“123456”然后换行。
  • spawn
    用来启动新的进程,spwan后的send和expect命令都是和使用spawn打开的进程进行交互。示例如下:
spawn ssh-copy-id -f $user_hostname
expect {
"(yes/no)?"
{
send "yes\n"
expect "*assword:" { send "$password\n"}
}
"*assword:"
{
send "$password\n"
}
}

该段命令的作用是:启动一个ssh-copy-id进程,把当前服务的ssh认证文件复制到对应的user_hostname,实现当前服务于user_hostname 进行免密操作。

  • interact
    允许用户进行交互。
实例讲解

下面通过参数输入进行ssh-copy-id脚本autosshcopyid.exp内容如下:

#!/usr/bin/expect
set timeout 10
set user_hostname [lindex $argv 0]
set password [lindex $argv 1]
spawn ssh-copy-id -f $user_hostname
expect {
"(yes/no)?"
{
send "yes\n"
expect "*assword:" { send "$password\n"}
}
"*assword:"
{
send "$password\n"
}
}

​#!/usr/bin/expect​​:表示使用expect来解释该脚本。

​set timeout 10​​:设置超时时间,单位是秒,默认情况下是10秒。

​set user_hostname [lindex $argv 0]​​:把第一个参数传递给给user_hostname 变量。

​set password [lindex $argv 1]​​:把第二个参数传递给password 变量。

​spawn ssh-copy-id -f $user_hostname​​: 启动新的进程ssh-copy-id,并获取进程user_hostname

expect { 
"(yes/no)?" #如果匹配(yes/no)?
{
send "yes\n" #通过send命令输入"yes"并换行
expect "*assword:" #如果字符串匹配assword:
{
send "$password\n" #通过send命令输入命令设置的密码并换行
}
}
"*assword:" #如果匹配assword?
{
send "$password\n" #通过send命令输入命令设置的密码并换行
}
}