expect工具的使用
一、介绍
我们通过Shell可以实现简单的控制流功能,如:循环、判断等,但是对于需要交互的场合则必须通过人工来干预。
有时候我们可能会需要实现和交互程序如telnet服务器等进行交互的功能,一般来说这些输入都需要手工输入进行的,而expect则可以根据程序的提示模拟标准输入提供给程序需要的输入来实现交互程序执行。
所以,这时候只要知道对方机器的账号和密码就可以通过expect脚本实现登录和执行远程命令。
二、语法
使用之前先安装 expect 软件
yum install -y expect
命令参数:
set:设置变量
spawn:调用命令
expect:捕捉用户输入的提示
send:发送需要交互的值
set timeout:设置超时时间(-1为永久)
interact:执行完成后保持交互状态
expect eof:与 spawn 对应表示捕获终端输出信息终止,类似于 if....endif
注:
expect 脚本必须以 interact 或 expect eof 结束,执行自动化任务通常 expect eof 就够了。
三、示例
以下是一个远程文件同步脚本
#! /usr/bin/expect
set passwd "远程主机登录密码"
# 传递参数1
set host [lindex $argv 0]
# 传递参数2
set file [lindex $argv 1]
# 通过调用rsync命令同步远程文件
# --files-from=$file表示要同步的多个文件路径保存在一个文件中
spawn rsync -av --files-from=$file / root@$host:/
expect {
# 第一次登录时会提示是否信任
"yes/no" { send "yes\r"}
# 输入密码
"password:" { send "$passwd\r" }
}
expect "]*"
# 查看系统负载
send "w\r"
# 如果想要停留在远程主机,则使用interact
expect eof
四、错误案例
rsync默认使用ssh协议传输文件,而由于远程主机的ssh不是修改了默认端口,所以rsync在同步的时候需要指定端口:
# expect脚本部分内容如下
spawn rsync -avP -e 'ssh -p 1234' $file $host:/
执行后报错:
Missing trailing-' in remote-shell command.
这是由于脚本中的引号失效所致,将rsync部分修改如下:
rsync -avP -e "ssh -p 1234" $file $host:/
再次执行后成功。