【问题标题】:Expect Script Crash After exp_close and exp_waitexp_close 和 exp_wait 后预期脚本崩溃
【发布时间】:2015-10-23 17:44:32
【问题描述】:

我的目标是确定这些主机用来进行身份验证的 TACACS 服务器的 IP 地址。

当我运行我的脚本时,Unix ops 抱怨说(进程?)表被“defunct”填满。

根据在线研究,我认为“exp_close”和“exp_wait”会消除这种情况。我添加了这些行。

如果我没记错的话,ssh 可以工作,但是在脚本回退到 telnet 的地方(因为这是允许的所有远程设备),脚本崩溃了。

请帮助我正确设置语法,这样无论是否使用 SSH/telnet,脚本都能正常运行;谢谢!

(PS。Telnet 是我老板的选择,不是我的;而且他目前不打算改变)

spawn ssh -q $USER@$line

    set ssh_id $spawn_id

expect {

eof      {spawn telnet -l $USER $line}

}

expect {
eof      {continue}
}

expect {
-re "\[Uu]sername"  {send "$USER\r"}
}

expect {

"(yes/no)"  { send "yes\r";exp_continue}
}   

expect -re  "\[Pp]assword:" {send "$pass\r"}
expect      "#"


send        "show run | include ip tacacs source-interface\r"
expect      "#"
send        "exit\r"

exp_close -i $ssh_id
exp_wait -i  $ssh_id
             }
exit 0
log_file

【问题讨论】:

  • 你得到的错误是什么?共享输出会更好。

标签: bash crash automation tcl expect


【解决方案1】:

我希望在切换到使用 telnet 时无法关闭用于 ssh 的 PTY 可能会导致一些问题,尤其是在并行运行此脚本的许多实例时。因此,你会改变:

spawn ssh -q $USER@$line

    set ssh_id $spawn_id

expect {

eof      {spawn telnet -l $USER $line}

}

到这里:

spawn ssh -q $USER@$line
set ssh_id $spawn_id

expect {
    eof {
        # Free up resources
        close
        wait
        # Start up the alternative
        spawn telnet -l $USER $line
        # Save it's ID (in a now-poorly-named variable)
        set ssh_id $spawn_id
    }
}

除此之外,这很奇怪:

expect {
eof      {continue}
}

除非在循环中,否则我不认为这是一个好主意。即便如此,这也不是一个好主意,因为在这种情况下它不会清理 PTY。你不包括循环,所以我不知道这是否是问题所在。

最后,这部分也很奇葩:

expect {
-re "\[Uu]sername"  {send "$USER\r"}
}

expect {

"(yes/no)"  { send "yes\r";exp_continue}
}   

expect -re  "\[Pp]assword:" {send "$pass\r"}
expect      "#"

您直接提供用户名,因此这个小序列的第一个 expect 子句应该是不必要的。其次,没有真正的理由将exp_continue 与单个子句一起使用,除非您打算等待超时(默认情况下退出expect)。最好将所有这些重写为:

expect {
    "(yes/no)"          { send "yes\r";   exp_continue }
    -re "\[Pp]assword:" { send "$pass\r"; exp_continue }
    "#"                 { list }
}

如果您必须在其中输入用户名(为什么??),那么这只是期望中的另一个子句。没有参数的list 命令实际上什么都不做,因为它的结果总是空字符串(这也是空列表)。

exit 之后写log_file 毫无意义。达不到; exit 没有结果,因为它使进程退出......

【讨论】:

  • 如果我从头开始重写,我会创建一个过程来封装所有除了循环和回退到 telnet,并确保该过程得到正确的清理。然后我将使用该过程来完成工作的核心并处理调用者中的回退/循环。在不泄漏资源的情况下使其工作会容易得多,因为它可以更完全地分离关注的级别。
  • Donal,非常感谢您抽出宝贵时间审查我的代码并提供反馈,非常感谢。
  • spawn ssh -q D2014@10.1.1.1 spawn_id: spawn id exp7 not open while execution "close" 从 "expect { eof { # 释放资源 close wait # 启动备用 spawn telnet -l $USER $line ..." ("foreach" body line 6) 从 "foreach line $TACACS_CLIENT { spawn ssh -q $USER@$line set ssh_id $spawn_id expect { eof { # 释放资源 close wai ...”(文件“./TACACS_LOOPBACK_IDENTIFICATION_EXPERIMENT.sh”第 18 行)我在您的修复中做错了什么......?
  • foreach line $TACACS_CLIENT { spawn ssh -q $USER@$line set ssh_id $spawn_id expect { eof { # 释放资源 close wait # 启动备用 spawn telnet -l $USER $line #保存它的 ID 设置 ssh_id $spawn_id } } 期望 "ALS1" 发送 "enable\r" 期望 "Password:" 发送 "password\r" 期望 "#" 发送 "show run | include tacacs-server host\r" 期望 "# " 发送 "exit\r" exp_close -i $ssh_id exp_wait -i $ssh_id } 退出 0
  • Donal,我做了一个“ps -ef | grep defunct”,但没有看到 telnet 或 ssh 的条目增加,我也没有看到 - 即使我的脚本继续运行。 foreach line $TACACS_CLIENT { spawn ssh $line expect { eof {wait; spawn telnet $line} } 期望 "ALS1>" 发送 "enable\r" 期望 "Password:" 发送 "password\r" 期望 "#" 发送 "show run | include tacacs-server host\r" 期望 "#" 发送"exit\r" 关闭等待 } 退出 0
猜你喜欢
  • 2013-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-01
  • 1970-01-01
相关资源
最近更新 更多