我正在尝试使用以下脚本通过 telnet 连接到我的路由器:
#!/usr/bin/expect -f
set timeout 20
# router user name
set name "admin"
# router password
set pass "admin"
# router IP address
set routerip "192.168.1.1"
# Read command as arg to this script
set routercmd "cat /var/1.leases"
# start telnet
spawn telnet $routerip
# send username & password
expect "username:"
send -- "$name\n"
expect "password:"
send -- "$pass\n"
# get out of ISP's Stupid menu program, go to shell
expect "TBS>>"
send -- "sh\n"
# execute command
expect -re ".*\$"
send -- "$routercmd\n"
# exit
send -- "^D"
现在,脚本运行良好,直到该send -- "sh\n"
部分。它进入 shell 提示符,如下所示:~ $
(tilda-space-dollar-space)。但是,此后我无法发出命令。此后它基本上不起作用。
有人能告诉我为什么吗?我是不是犯了什么错误?
答案1
好的。我破解了。这肯定与expect
代码最后几行中的错误模式匹配有关。
我首先做的是使用 生成一个录制脚本autoexpect
。此工具用于记录您的会话并基于此生成脚本。为此,我首先安装了软件包autoexpect
(expect-dev
在基于 Debian 的系统上可在软件包中找到),然后录制了我的会话:
sudo apt-get install expect-dev #Since I'm on Ubuntu
autoexpect telnet 192.168.1.1
autoexpect
自动为我生成了一个脚本。当我运行这个脚本时,它已经到达执行我的命令并在路由器中执行它,但随后无法退出。从这个脚本中得到提示并阅读 expect 手册页后,我终于发现模式识别存在一些问题。我最终相应地修改了脚本,这就是最终有效的:
#I am mentioning here only the end part of the complete script which was faulty
# execute command
expect "~ \$ "
send -- "$routercmd\r"
expect "~ \$ "
send -- "exit\r"
expect -- "TBS>>"
send -- "exit\r"
expect -- "*Are you sure to logout?*"
send -- "y"
expect eof
所以,我们学到的教训是,我们应该使用autoexpect
自动生成的脚本。然后,如果这些自动生成的脚本出现错误,很可能是由于零件中的模式识别错误造成的expect
。
就我的情况而言,本质上有问题的部分是:
expect -re ".*\$" #WRONG
expect "~ \$ " #RIGHT
故障部分将完全取决于您的会话以及您正在联系的人。通过 telnet 联系邮件服务器将返回不同的输出,您必须进行相应的匹配。