gpt4 book ai didi

session - 在期望中终止生成 session

转载 作者:行者123 更新时间:2023-12-04 12:08:55 25 4
gpt4 key购买 nike

我正在尝试解决登录到大量设备(数千个)的 Expect 脚本的问题。脚本大约有 1500 行,而且相当复杂;它的工作是审计具有数千个节点的网络上的管理设备。因此,它通过 telnet 登录设备,运行命令检查设备的健康状况,将此信息记录到文件中,然后注销以继续下一个设备。

这是我遇到问题的地方;每expect在我的脚本中包含一个超时和一个 eof,如下所示:

timeout {
lappend logmsg "$rtrname timed out while <description of expect statement>"
logmessage
close
wait
set session 0
continue
}
eof {
lappend logmsg "$rtrname disconnected while <description of expect statement>"
logmessage
set session 0
continue
}

我的最后 expect手动关闭每个生成 session :
-re "OK.*#" {
close
send_user "Closing session... "
wait
set session 0
send_user "closed.\n\n"
continue
}

假设 session = 0,继续将脚本带回启动下一个 spawn session 的 while 循环。

设置 session 0 跟踪生成 session 何时通过超时手动关闭或通过 EOF 在新生成 session 打开之前关闭,并且一切似乎都表明生成 session 正在关闭,但经过一千个左右生成的 session 后,我得到以下错误:
spawn telnet <IP removed>
too many programs spawned? could not create pipe: too many open files

现在,我是一名网络工程师,而不是 UNIX 管理员或专业程序员,所以有人可以帮助我解决我的错误吗?我是否关闭了 telnet spawn session 但没有正确关闭 channel ?我编写了第二个测试脚本,它实际上只是一个接一个地连接到设备,并在连接形成后立即断开连接。它不像我的主脚本那样登录或运行任何命令,并且可以通过数千个连接完美运行。该脚本如下:
#!/usr/bin/expect -f

#SPAWN TELNET LIMIT TEST

set ifile [open iad.list]
set rtrname ""
set sessions 0

while {[gets $ifile rtrname] != -1} {
set timeout 2
spawn telnet $rtrname
incr sessions
send_user "Session# $sessions\n"
expect {
"Connected" {
close
wait
continue
}
timeout {
close
wait
continue
}
eof {
continue
}
}

在我的主脚本中,我正在记录每个连接以及它们为什么会出现 EOF 或超时(通过将特定原因写入文件的 logmessage 进程),甚至当我只看到成功的产生连接和关闭的连接时,我得到我的主脚本有同样的问题,但测试脚本没有。

我一直在阅读有关终止进程 ID 的内容,但据我所知,close 应该终止当前 spawn session 的进程 ID,而 wait 应该暂停脚本,直到进程终止。我还尝试使用来自设备的简单“退出”命令来关闭 telnet 连接,但这并没有产生更好的结果。

我可能只需要一个关于如何更好地跟踪我的 session 的打开和关闭的建议,并确保在设备之间没有生成 session 保持打开状态。任何可以提供的帮助将不胜感激。

谢谢!

最佳答案

错误?

spawn telnet too many programs spawned? could not create pipe: too many open files



此错误可能是由于您的系统耗尽了文件句柄(或至少耗尽了您可用的计数)。

我怀疑这样做的原因是被放弃的 telnet session 保持打开状态。

现在让我们谈谈为什么他们可能仍然闲逛。

差远了?

Close 可能实际上并不会关闭 telnet 连接,尤其是当 telnet 无法识别 session 已关闭时,只能期望与 telnet 的 session (See: The close Command) .在这种情况下,Telnet 最有可能保持事件状态,等待来自网络端的更多输入和 TCP 保持事件状态。

并非所有应用程序都能识别 close,它作为 EOF 呈现给接收应用程序。因此,即使它们的输入已关闭,它们也可能保持打开状态。

告诉“Telnet”,它结束了。

在这种情况下,您将需要中断 telnet。如果您的意图是完成一些工作并退出。那么这正是我们需要做的。

对于“telnet”,您可以通过发出“send “35\r””(如果您必须自己输入,则在键盘上是“ctrl+]”),然后是“quit”和回车,干净地退出。这将告诉 telnet 正常退出。

Expect script: start telnet, run commands, close telnet
摘抄:
#!/usr/bin/expect
set timeout 1
set ip [lindex $argv 0]
set port [lindex $argv 1]
set username [lindex $argv 2]
set password [lindex $argv 3]
spawn telnet $ip $port
expect “‘^]’.”
send – – “\r”
expect “username:” {
send – – “$username\r”
expect “password:”
send – – “$password\r”
}
expect “$”
send – – “ls\r”
expect “$”
sleep 2
# Send special ^] to telnet so we can tell telnet to quit.
send “35\r”
expect “telnet>”
# Tell Telnet to quit.
send – – “quit\r”
expect eof
# You should also, either call "wait" (block) for process to exit or "wait -nowait" (don't block waiting) for process exit.
wait

等待,为完成。

Expect - The wait Command

如果没有“等待”,expect 可能会过早地切断与进程的连接,这在一些罕见的情况下会导致创建僵尸。如果应用程序没有更早地收到我们的信号(来自关闭的 EOF),或者如果进程没有将 EOF 解释为退出状态,那么它也可能继续运行并且您的脚本将不会更明智。通过等待,我们确保在进程清理和退出之前不会忘记进程。

否则,在预期退出之前,我们可能不会关闭任何这些进程。如果长时间运行的expect脚本(或连接到许多服务器的脚本)没有关闭文件句柄,这可能会导致我们用完文件句柄。一旦我们用完文件句柄,expect 并且它开始的所有东西都会消失,并且您不会再看到这些文件句柄耗尽了。

超时?,捕获所有?,为什么?

您可能还需要考虑使用“超时”,以防服务器没有按预期响应,以便我们可以提前退出。这对于严重滞后的服务器来说是理想的,这些服务器应该引起一些管理员的注意。

Catch all 可以帮助您的脚本处理任何意外的响应,这些响应不一定会阻止我们继续。我们可以选择继续处理,也可以选择提前退出。

Expect Examples摘抄:
expect {           
"password:" {
send "password\r"
} "yes/no)?" {
send "yes\r"
set timeout -1
} timeout {
exit
# Below is our catch all
} -re . {
exp_continue
#
} eof {
exit
}
}

关于session - 在期望中终止生成 session ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19774016/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com