【问题标题】:Connecting to switches using SSH and Expect使用 SSH 和 Expect 连接到交换机
【发布时间】:2014-10-17 21:46:41
【问题描述】:

我是一个可以期待的新手(虽然有很多 shell 编程)。 我正在尝试使用 expect 连接到交换机,以便能够转储它正在运行的配置。但不知何故,我的发送命令似乎没有发送到交换机。

脚本:

#!/usr/bin/expect -f

proc connect {passw} {
  expect {
    "assword:" {
      send "$passw\r"
        expect {
          "Prompt>" {
            return 0
          }
        }
    }
  }
   # timed out
   return 1
 }

set user [lindex $argv 0]
set passw [lindex $argv 1]
set host [lindex $argv 2]

#check if all were provided
if { $user == "" || $passw == "" || $host == "" } {
  puts "Usage: <user> <passw> <host>\n"
  exit 1
}

spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no $user@$host
set rez [connect $passw]
if { $rez == 0 } {
    send {enable\r}
    send {show running\r}
    exit 0
}
puts "\nError connecting to switch: $host, user: $user!\n"
exit 1

唉,当我运行脚本(从 shell 脚本触发)时,我可以看到它登录到交换机并看到“提示”,但之后脚本似乎退出了,因为我没有看到“启用”和正在执行的“显示运行”命令。

谁能告诉我如何解决这个问题?

理查德。

【问题讨论】:

  • 不是答案(因此是评论),但您可能想看看 rancid (shrubbery.net/rancid) 是如何做到这一点的。

标签: ssh tcl expect


【解决方案1】:

您需要在使用send 发送命令后进一步添加expect 语句。

spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no $user@$host
set rez [connect $passw]

set prompt "#"

if { $rez == 0 } {
    send {enable\r}
    expect $prompt; # Waiting for 'prompt' to appear
    send {show running\r}
    expect $prompt; # Waiting for the prompt to appear
    exit 0
}

在使用send 之后没有expect 命令,那么expect 对ssh 进程没有任何期望,它只会以更快的方式发送命令,这就是你无法获得任何输出的原因。

另一个更新:

您正在使用单独的proc 进行登录。如果您使用单独的proc,则建议您传递生成句柄。否则,脚本可能会失败。原因是,它不会从进程发送/期望,而是从标准输入发送/期望。所以,你应该这样使用它,

proc connect {passw handle} {
  expect {
    -i $handle 
    "assword:" {
      send "$passw\r"
        expect {
          -i $handle
          "Prompt>" {
            return 0
          }
        }
    }
  }
   # timed out
   return 1
 }

 set handle [ spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no $user@$host ] 
 set rez [connect $passw $handle ]
 set prompt "#"
 if { $rez == 0 } {
    send -i $handle "enable\r"
    expect -i $handle $prompt
    send -i $handle "show running\r"
    expect -i $handle $prompt
    exit 0
} 

我们将 ssh spawn 句柄保存到变量 'handle' 中,它与 sendexpect 一起使用,并且标志 -i 用于使它们等待相应的进程

【讨论】:

  • spawn_id 是全局的,并且期望使用与 Tcl 不同的作用域机制:您不必将 spawn_id 显式传递给 proc。
  • 是的,格伦。正确的。我这样做是为了避免任何可能的问题,比如脚本中使用了多个 spawn
【解决方案2】:

@Dinesh 给出了主要答案。其他几点说明:

  • send {enable\r} -- 由于您使用大括号而不是引号,因此您发送的字符是 \r 而不是回车。
  • 你从connect 返回 0 和 1,就像你是一个 shell 程序员一样(不是侮辱,我也是)。请改用 Tcl 的布尔值。

快速重写:

#!/usr/bin/expect -f

set prompt "Prompt>"
proc connect {passw} {
    expect "assword:" 
    send "$passw\r"
    expect {
        $::prompt {return true}
        timeout   {return false} 
    }
}

lassign $argv user passw host

#check if all were provided
if { $user == "" || $passw == "" || $host == "" } {
    puts "Usage: [info script] <user> <passw> <host>"
    exit 1
}

spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no $user@$host
if {[connect $passw]} {
    send "enable\r"
    expect $::prompt
    send "show running\r"
    expect $::prompt
    send "exit\r"         # neatly close the session
    expect eof
} else {
    puts "\nError connecting to switch: $host, user: $user!\n"
}

【讨论】:

    猜你喜欢
    • 2013-04-30
    • 1970-01-01
    • 2019-12-24
    • 1970-01-01
    • 1970-01-01
    • 2011-12-30
    • 1970-01-01
    • 1970-01-01
    • 2018-09-14
    相关资源
    最近更新 更多