我正在编写一个 Expect 脚本,用于从我的主机中提取配置信息。
问题是,我的某些主机(输入启用命令时)会提示输入登录名和密码。这主要是较旧的 HP 套件,但我在其他地方也遇到过这种情况。
如果这是合法语法,那么像下面这样的嵌套 expect 语句就可以做到这一点。我该如何实现这一点?
expect {
default { send_user "\nEnable Mode Failed - Check Password\n"; exit 1 }
"*\#" {}
"*>" {
send "enable\n"
expect{
"Login" {
send "$username\n"
}
default {}
}
expect "*assword"
send "$enablepassword\n"
expect "*\#"
}
}
我知道我的语法只是稍微偏离了一点 - 我已经看到很多描述使用嵌套期望的参考资料 - 但就我而言,我无法完全理解它。
答案1
你可以这样写:
exp_internal 1
expect {
default { send_user "\nEnable Mode Failed - Check Password\n"; exit 1 }
"*>" {
send "enable\r"
expect{
"Login" {
send "$username\r"
exp_continue
}
"*assword" {
send "$enablepassword\r"
}
}
# Now, look back to the outer expect to continue expecting the "#" prompt
exp_continue
}
"*#"
}
- 使用
exp_internal 1
启用调试 - 用以下方式终止
send
命令\r
(回车键是“按下回车键”) exp_continue
在包含的内容内循环expect
以继续寻找其他模式。
答案2
非常感谢 Glenn,我得到了一个脚本,它可以让我从我的各种 Cisco 或 HP 设备中提取信息。
#!/usr/bin/expect -f
set hostname [lindex $argv 0];
set username [lindex $argv 1];
set password [lindex $argv 2];
set enablepassword [lindex $argv 3];
spawn ssh -o StrictHostKeyChecking=no $username\@$hostname
expect {
timeout { send_user "\nTimeout Exceeded - Check Host\n"; exit 1 }
eof { send_user "\nSSH Connection To $hostname Failed\n"; exit 1 }
"*\#" {}
"*assword:" {
send "$password\n"
}
}
# This allows for handling any of the various HP login screens.
sleep 5
send " "
sleep 5
send "3\n"
sleep 5
expect {
"*>" {
send "enable\n"
expect {
"*ogin" {
send "$username\n"
}
}
expect {
"*assword" {
send "$enablepassword\n"
exp_continue
}
exp_continue
}
}
"*\#" {}
default { send_user "\nEnable Mode Failed - Check Password\n"; exit 1 }
}
# Disable paging. This is both the HP and Cisco statements.
send "terminal length 0\n"
send "no page\n"
expect "*\\#"
log_file -noappend ./$hostname
send "show run\n"
expect "#\n"
log_file
send "end\n"
expect "\#"
expect "\#"
send "exit\n"
expect ":~\$"
exit