繁体   English   中英

如何在Shell脚本(如嵌套If Else循环)中使用Expect?

[英]How to use expect in Shell script like nested If Else loop?

我在Shell脚本下面编写了脚本,该脚本旨在通过执行SSH并执行命令从远程主机获取模型名称。

#!/bin/bash

> output.csv

IFS=","

echo "IP,Model Name" >> output.csv

while read ip
do
    #echo "Current IP is: $ip"      

    model=expect -c 'spawn ssh username@'"$ip"' "show version | in cisco"; expect -re "The.*(yes/no)?"; send "yes\r";  expect -re ".*UNAUTH.*password:"; send "password\r";' | grep cisco

    echo "$ip,$model" >> output.csv

done < Check_SSH.csv

当我手动执行以下命令时,它将给出预期的模型名称作为输出。

命令: expect -c 'spawn ssh username@'"$ip"' "show version | in cisco"; expect -re "The.*(yes/no)?"; send "yes\\r"; expect -re ".*UNAUTH.*password:"; send "password\\r";' | grep cisco expect -c 'spawn ssh username@'"$ip"' "show version | in cisco"; expect -re "The.*(yes/no)?"; send "yes\\r"; expect -re ".*UNAUTH.*password:"; send "password\\r";' | grep cisco

但是,当将其放入上述脚本中时,不会产生任何输出。

另外,在大多数服务器上都配置了MOTD(每日消息),以及将服务器添加到.ssh/known_hosts主机的真实性... ”消息,因此我尝试在脚本中处理它们,但是Expect无法处理MOTD不出现或.ssh/known_hosts已经存在remote的情况。

非常感谢您提供任何帮助以使此脚本运行。

预期产量:

IP,Model Name
8.8.8.8,C9407R
8.8.8.1,C9407R
8.8.8.2,C9407R
8.8.8.3,C9407R

首先,您缺少执行期望代码的Command Substitution语法:

model=$(expect -c ...)
# ....^^.............^

接下来,要选择期望模式,您需要expect {patt1 action1 patt2 action2 ...}形式:

expect -c '
    spawn ssh username@'"$ip"' "show version | in cisco"
    expect {
        -re "The.*(yes/no)?"      {send "yes\r"; exp_continue}
        -re ".*UNAUTH.*password:" {send "password\r"; exp_continue}
        eof
    }
'

这样,expect可以匹配任何模式。 exp_continue命令“循环”同里expect的命令,所以你可以匹配他们的不止一个。 当“ show version ...”命令完成后ssh连接关闭时, eof模式匹配。

换行符以提高可读性。

放在一起:

model=$(
    expect -c '
        spawn ssh username@'"$ip"' "show version | in cisco"
        expect {
            -re "The.*(yes/no)?"      {send "yes\r"; exp_continue}
            -re ".*UNAUTH.*password:" {send "password\r"; exp_continue}
            eof
        }
    ' | grep -i cisco
)

我觉得grep部分还需要做更多的事情,但是您并不仅显示了Expect命令的输出。


更新:

  1. 使用spawn -noecho ssh ...因此,期望不会打印spawn命令。
  2. 然后,您将获得登录过程需要显示的ssh输出,然后显示“ show”命令:
    • 如果期望输出恰好为1行,则可能需要将grep更改为tail -n 1
    • 否则,请显示您获得的输出,我们可以帮助您滤除噪声。

更新2:滤除噪音

我将假设正则表达式模式cisco (.*) processor是您需要匹配的:

model=$(
    expect -c '
        log_user 0
        spawn ssh username@'"$ip"' "show version | in cisco"
        expect {
            -re "The.*(yes/no)?"       {send "yes\r"; exp_continue}
            -re ".*UNAUTH.*password:"  {send "password\r"; exp_continue}
            -re "cisco (.*) processor" {puts $expect_out(1,string)}
        }
        expect eof
    '
)

log_user 0关闭生成的进程写入stdout的功能。 Expect仍然可以捕获其输出。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM