我正在尝试通过expect脚本从交换机获取配置详细信息。
当我通过shell手动调用时,我有下面的工作正常。
但是当同样调用via时,php (构建一个web接口来调用它)不知何故expect_out(缓冲区)没有填满所有行,我的匹配失败了。
我正在尝试匹配设置或未设置的配置位。
同样,代码在手动调用时也能正常工作,只是通过php无法填充expect_out(buffer) :( :(
正常工作的代码。
#!/usr/bin/expect
set ip ROUTER_IP
set uname USER_NAME
set psd PASSWORD
set log_file -a "/tmp/script.log"
spawn /usr/bin/ssh $uname@$ip
expect {
"ord:" {
send "$psd\r"
expect {
"> " {
send "\r"
set cmd "show configuration | display set | match class | match rancid"
set values $expect_out(buffer)
send_log "\nbefore trim n match -$values-\n"
set values [string trim $values]
send_log "\nbefore match -$values-\n"
set found [regexp {match rancid\s+(.*)\s+\r\n\{.*} $values match px]
if { $found == 1 && $px != "" } {
puts "Rancid Exists... !!!"
send "exit\r"
exit 1
} else {
puts "Coundnt find Rancid ... !!!"
send "exit\r"
exit 2
}
}
"denied: " {
puts "ERROR: Access Denied"
exit 2
}
}
}
}我通过php调用它,如下所示
$res=shell_exec("/usr/bin/expect $scriptPath ");我可以看到,设置为$values的expect_out(缓冲区)正在被从log_file输出的半个命令填充。
Succesfull expect_out(缓冲区),
before trim match -show configuration | display set | match class | match rancid ^M
set system login user rancid class remote-backup^M
^M
{master:1}^M
USER_NAME@SWITCH> -
before match -show configuration | display set | match class | match rancid ^M
set system login user rancid class remote-backup^M
^M
{master:1}^M
USER_NAME@SWITCH>-当通过php调用时,expect_out(buffer)如下所示:
before trim match -show configuration | display set | m^MUSER_NAME@SWITCH> -
before match -show configuration | display set | m^MUSER_NAME@SWITCH>-不知何故,当expect脚本通过php调用时,buffer并没有输出所有的命令,所以匹配失败。
谁能告诉我什么可能是mistake.Thanks。
发布于 2019-07-04 03:26:17
为什么事情会有所不同?好吧,可能有各种各样的原因。不同的时间可能是其中之一;这是很有可能的,也很难预防。您只需编写代码以适应这种变化;幸运的是,这相当容易。
通常,不建议使用$expect_out(buffer)本身,因为它没有定义在其中累积了多少数据。它可能会有与expected模式匹配所需的内容,但实际上不能保证匹配比这更多的内容。我希望脚本更像这样:
#!/usr/bin/expect
set ip ROUTER_IP
set uname USER_NAME
set psd PASSWORD
set log_file -a "/tmp/script.log"
spawn /usr/bin/ssh $uname@$ip
# Less nesting here! Makes the code much simpler to read
expect "ord:"
send "$psd\r"
expect {
"> " {
send_log "logged in\n"
}
"denied: " {
puts "ERROR: Access Denied"
exit 2
}
}
# Classic code to read a multi-line result from a remote site, ONE LINE AT A TIME
set cmd "show configuration | display set | match class | match rancid"
send "$cmd\r"; # Had you forgotten this in pasting?
set values ""
expect {
-re {^(.*\S|)\r?\n} {
append values $expect_out(1,string) "\n"
exp_continue
}
"> " {
# Got the prompt again
}
}
# This is your code again
send_log "\nbefore trim n match -$values-\n"
set values [string trim $values]
send_log "\nbefore match -$values-\n"
set found [regexp {match rancid\s+(.*)\s+\r\n\{.*} $values match px]
if { $found == 1 && $px != "" } {
puts "Rancid Exists... !!!"
send "exit\r"
exit 1
} else {
puts "Coundnt find Rancid ... !!!"
send "exit\r"
exit 2
}通常,您应该尝试构建代码的结构,以便交错您的expect和send,尽管一行中包含几个expect的序列也可以。但是,您可以将其视为直到下一个expect才真正处理send。
注意exp_continue的用法。这是Expect的一个非常强大的特性,它允许您保持当前的expect语句进行更多的匹配。它允许您构建匹配器循环,就像我所做的那样,并极大地简化了许多交互问题。看在上帝的份上,尽量避免代码嵌套!即使不使程序变得特别复杂,程序也够难的了!
https://stackoverflow.com/questions/56875358
复制相似问题