expect_out(buffer)在通过php调用时不会捕获所有数据
我试图通过expect脚本从交换机获取配置详细信息expect_out(buffer)在通过php调用时不会捕获所有数据,php,tcl,expect,Php,Tcl,Expect,我试图通过expect脚本从交换机获取配置详细信息当我通过shell手动调用时,以下工件工作正常。 但是,当同样的调用via时,php(构建一个web界面来调用它)不知何故地expect_out(缓冲区)没有填满所有的行,我的匹配失败。 我正在尝试匹配或不匹配配置位集。 同样,当手动调用代码时,代码也可以工作,只是通过php,它无法以某种方式填充expect_out(缓冲区):(:( 工作代码。 #!/usr/bin/expect set ip ROUTER_IP set uname USER_
当我通过shell手动调用时,以下工件工作正常。
但是,当同样的调用via时,php(构建一个web界面来调用它)不知何故地expect_out(缓冲区)没有填满所有的行,我的匹配失败。
我正在尝试匹配或不匹配配置位集。
同样,当手动调用代码时,代码也可以工作,只是通过php,它无法以某种方式填充expect_out(缓冲区):(:( 工作代码。
#!/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 ");
before trim match -show configuration | display set | m^MUSER_NAME@SWITCH> -
before match -show configuration | display set | m^MUSER_NAME@SWITCH>-
我可以看到,expection out(buffer)被设置为$values,它被日志文件输出的一半命令填充。成功期望输出(缓冲区) 当通过php调用时,expect_out(缓冲区)如下所示,
$res=shell_exec("/usr/bin/expect $scriptPath ");
before trim match -show configuration | display set | m^MUSER_NAME@SWITCH> -
before match -show configuration | display set | m^MUSER_NAME@SWITCH>-
不知何故,当通过php调用expect脚本时,buffer没有输出所有命令,匹配失败。
有人能告诉我可能的错误是什么。谢谢。为什么事情会不同?可能有各种各样的原因。不同的时间可能是其中之一;这很有可能,也很难防止。你只需要编写代码以适应变化;幸运的是,这相当容易 一般来说,不建议使用
$expect\u out(buffer)
本身,因为它没有定义其中累积了多少数据。它可能有足够的数据来匹配expect
ed模式,但实际上不能保证匹配更多的数据。我希望脚本更像这样:
#!/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
s和send
s交织在一起,虽然一行中有几个expect
s可以。但是,您可以将其视为直到下一个expect
才真正处理send
请注意使用了
exp\u continue
。这是Expect的一个非常强大的功能,它可以让当前的Expect
语句进行更多的匹配。它可以让您构建匹配器循环,就像我做的那样,并大大简化了许多交互问题。看在上帝的份上,尽量避免嵌套代码!程序已经够难了,但又不会使它们变得特别复杂!计算的一个深刻事实是,只要环境发生变化,在自己的机器上正常运行的简单程序就会失败(而web服务器是另一种环境)。编写代码以适应需要更多的工作-虽然在本例中没有太多-并且意味着它不会在您不期望的情况下突然中断。感谢代码片段@donal。是的,这些环境很难处理。您能帮助我理解带有{.*\n}的独立expect块吗exp_continue part?match regex上要更改的内容看起来像是,它现在不工作了,日志-日志帮助很大!看看它,你真的在寻找文本{master:1}
?如果你在寻找特定的内容,那么让expect工作就容易多了。(我们需要移动模式以提取模式上方的真实数据,以匹配提示;匹配顺序)。核心问题是,由于时间差异(超出我们的控制),我们在匹配缓冲区中一次获得多行。我尝试在{master:1}之前匹配字符串,基本上是在之前匹配字符串{.所以,如果已经创建了用户类,那么show commad将输出一些东西,如果没有,它将返回空的,因此我尝试在{之前放置/匹配东西,并将其存储在px变量中。我也尝试过在regex下面,但似乎没有一个起作用:(set found[regexp{.$cmd\r\n(.*login user rancid class remote backup)\s+\r\n\{.*}$value match px]
找到集合[regexp{.*.*rancid\s+\r\n\{.*}$value match px]
好的,我不太确定如何确定您是否找到了任何内容,因为我不知道匹配的格式…但我很确定如何提取您关心的数据。假设您关心的行末尾没有空格。接下来的问题只是确定字符串何时匹配,以及而不是如何说服路由器告诉你这些信息。