使用SSH和Expect连接到交换机

时间:2014-10-17 12:21:04

标签: ssh tcl expect

我是一个期待的新手(虽然很多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脚本触发)时,我可以看到它登录到交换机并看到“提示”,但之后脚本似乎退出,因为我没有看到'启用'和'show running'命令正在执行。

任何人都可以告诉我如何解决这个问题?

理查德。

2 个答案:

答案 0 :(得分:1)

使用expect发送命令后,您需要添加更多send语句。

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
}

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

又一次更新:

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

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用于使它们等待对于相应的过程

答案 1 :(得分:0)

@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"
}