我的目标是确定这些主机用于进行身份验证的TACACS服务器的IP地址。
当我运行我的脚本时,Unix操作系统抱怨说(进程?)表填满了" 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
答案 0 :(得分: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
命令实际上没有任何作用,因为它的结果总是空字符串(也是空列表)。
log_file
之后写exit
是没有意义的。它不会达到; exit
没有结果,因为它会使流程退出...