一、Expect介绍
expect 是一个用于自动化交互式任务的工具,通常在命令行脚本中使用。它可以模拟用户输入并读取命令行程序的输出,从而实现自动化和批处理任务。expect 最初是为了在交互式环境中与 Telnet、SSH、FTP 等网络服务进行自动化交互而设计的,但也可以用于其他任何需要模拟用户交互的情况。
以下是 expect 的一些特点和功能:
- 自动化交互:
expect允许你编写脚本来模拟用户的交互行为,包括输入文本、等待特定的输出、匹配文本、从输出中提取信息等。 - 处理交互式程序:
expect可以用于与需要用户交互的命令行程序进行交互,例如 Telnet、SSH、FTP 等。它可以提供自动化的方式来登录、执行命令并处理输出。 - 条件匹配:
expect具有条件匹配功能,可以基于输出中的文本模式来决定下一步的操作。这使得你可以编写灵活的脚本来处理不同的情况。 - 脚本语言:
expect脚本是一种脚本语言,支持流程控制、变量、函数等基本编程功能,使得脚本更具可读性和可维护性。 - 模块化: 除了命令行外,
expect还提供了expect模块,可以用于其他编程语言(如 Tcl、Perl、Python)中,从而将自动化交互功能集成到更大的自动化任务中。 - 跨平台:
expect在各种 Unix/Linux 系统中可用,并且有一些变体和替代工具可以在不同环境中使用。
要使用 expect,你通常需要编写一个脚本,其中包含了预期的交互步骤。这个脚本会执行预期的交互操作,等待特定的输出并根据输出来决定下一步的操作。尽管 expect 在某些情况下很有用,但在一些场pexpect 库。
二、安装工具
Expect工具是依赖tcl的,所以需要先检查是否安装tcl
[root@localhost ~]# whereis tcl
tcl: /usr/lib64/tcl8.5 /usr/share/tcl8.5
- 如果没有安装运行下面命令安装
[root@localhost ~]# yum install -y tcl
[root@localhost ~]# yum install -y expect
- 查看expect的安装路径
[root@localhost ~]# command -v expect
/usr/bin/expect
二、选项介绍
当使用 expect 脚本来自动化交互时,你会用到一些关键的命令和函数。下面是对这些命令和函数的详细参数介绍:
spawn <command>: 启动一个新的交互式进程,后面跟着需要执行的命令或程序。expect <pattern> {action}: 从进程的输出中等待匹配<pattern>的文本,如果匹配成功,就执行{action}中指定的动作。可以多次使用expect来匹配不同的模式。send <string>: 向当前交互进程发送指定的字符串。send -- "<string>": 用于发送包含特殊字符的字符串,防止特殊字符被解释。exp_send <string>: 与send功能相同,用于发送指定的字符串信息。exp_continue: 在expect中使用,用于文章来源(Source):https://dqzboy.com 继续匹配后续的模式,而不是结束脚本执行。send_user <string>: 打印输出信息,相当于在脚本中使用echo命令。interact: 允许用户交互,使脚本暂停并将控制权交还给用户。exit: 退出expect脚本。eof: 表示expect脚本执行结束,退出。set <variable> <value>: 定义变量并赋值。puts <string>: 输出指定的字符串。set timeout <seconds>: 设置超时时间,如果在指定的时间内没有匹配到期望的输出,脚本将执行超时处理。
这些命令和函数的组合可以让你编写能够模拟用户交互的自动化脚本。当你在编写 expect 脚本时,可以根据实际情况结合使用这些命令,以达到预期的自动化交互效果。
三、使用实践
1、免交互拷贝公钥
1.1:编辑脚本
[root@localhost ~]# vim autocopy.exp
#!/usr/bin/expect
# 设置超时时间为10秒
set timeout 10
# 从命令行参数获取远程主机名和密码
set user_hostname [lindex $argv 0]
set password [lindex $argv 1]
# 启动 ssh-copy-id 命令,并将远程主机名传递给它
spawn ssh-copy-id $user_hostname
# 使用 expect 进行模式匹配和交互操作
expect {
"(yes/no)?" {
# 如果遇到 "(yes/no)?" 提示,自动发送 "yes" 并等待密码提示
send "yes\n"
expect "*assword:" {
# 发送密码并等待完成
send "$password\n"
}
}
"*assword:" {
# 如果直接遇到密码提示,发送密码并等待完成
send "$password\n"
}
}
# 等待并处理脚本执行结束
expect eof
[root@localhost ~]# chmod +x autocopy.exp
这个脚本做了以下事情:
- 设置了超时时间为10秒,确保在一定时间内完成交互操作。
- 从命令行参数获取了远程主机名和密码。
- 启动
ssh-copy-id命令,该命令将远程主机名传递给它,以便复制 SSH 公钥。 - 使用
expect进行模式匹配和交互操作,处理不同情况下的交互提示。 - 最后,等待脚本执行结束。
1.2:测试使用
[root@localhost ~]# ./autocopy.exp root@192.168.66.100 密码

2、SCP自动应答脚本
2.1:编辑脚本
[root@localhost ~]# vim autocopy.exp
#!/usr/bin/expect
# 设置超时时间为10秒
set timeout 10
# 从命令行参数获取远程主机名、源文件、目标文件和密码
set user_hostname [lindex $argv 0]
set src_file [lindex $argv 1]
set dest_file [lindex $argv 2]
set password [lindex $argv 3]
# 启动 scp 命令,将源文件复制到远程主机的目标位置
spawn scp $src_file $user_hostname:$dest_file
# 使用 expect 进行模式匹配和交互操作
expect {
"(yes/no)?" {
# 如果遇到 "(yes/no)?" 提示,自动发送 "yes" 并等待密码提示
send "yes\n"
expect "*assword:" {
# 发送密码并等待完成
send "$password\n"
}
}
"*assword:" {
# 如果直接遇到密码提示,发送密码并等待完成
send "$password\n"
}
}
# 等待复制完成的 "100%" 提示
expect "100%"
# 等待并处理脚本执行结束
expect eof
[root@localhost ~]# chmod +x autocopy.exp
这个脚本做了以下事情:
- 设置了超时时间为10秒,确保在一定时间内完成交互操作。
- 从命令行参数获取了远程主机名、源文件、目标文件和密码。
- 启动
scp命令,将源文件复制到远程主机的目标位置。 - 使用
expect进行模式匹配和交互操作,处理不同情况下的交互提示。 - 等待复制完成的 “100%” 提示,以确保文件复制完成。
- 最后,脚本等待执行结束并退出。
2.2:测试使用
- 用法:
autoscp.exp [user@]hostname 源文件 目标目录 [password] - 说明:该自动回答脚本可以自动完成主机验证和密码认证,即使已经是实现公钥认证的机器也没问题,因为公钥认证机制默认优先于密码认证,且此脚本的password项是可选的,当然,在没有实现公钥认证的情况下,password是必须项,否则expect实现非交互的目的就失去意义了。

必须 注册 为本站用户, 登录 后才可以发表评论!