使用SSH和Expect连接到交换机
我是一个新手(尽管有很多shell编程)。 我正在尝试使用expect连接到交换机,以便能够转储它正在运行的配置。但不知何故,我的发送命令似乎没有发送到交换机 脚本:使用SSH和Expect连接到交换机,ssh,tcl,expect,Ssh,Tcl,Expect,我是一个新手(尽管有很多shell编程)。 我正在尝试使用expect连接到交换机,以便能够转储它正在运行的配置。但不知何故,我的发送命令似乎没有发送到交换机 脚本: #!/usr/bin/expect -f proc connect {passw} { expect { "assword:" { send "$passw\r" expect { "Prompt>" { return 0
#!/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
#/usr/bin/expect-f
进程连接{passw}{
期待{
“assword:”{
发送“$passw\r”
期待{
“提示>”{
返回0
}
}
}
}
#超时
返回1
}
设置用户[lindex$argv 0]
设置密码[lindex$argv 1]
设置主机[lindex$argv 2]
#检查是否提供了所有信息
如果{$user==“”| |$passw==“”| |$host==“”}{
放置“用法:\n”
出口1
}
spawn ssh-oStrictHostKeyChecking=no-oCheckHostIP=no$user@$host
设置rez[连接$passw]
如果{$rez==0}{
发送{启用\r}
发送{显示正在运行\r}
出口0
}
放置“\n连接到交换机时出错:$host,用户:$user!\n”
出口1
唉,当我运行脚本(由shell脚本触发)时,我可以看到它登录到交换机并看到“提示符”,但之后脚本似乎退出,因为我看不到正在执行的“enable”和“show running”命令
谁能告诉我怎么解决这个问题
Richard。在使用
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
,建议您传递生成句柄。否则,脚本可能会失败。原因是,它将从stdin发送/expect,而不是从进程发送/expect。所以,你应该这样使用它
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'
中,它与send
和expect
一起使用,并使用标志-i
使它们等待相应的进程@Dinesh拥有主要答案。还有几点需要注意:
——由于使用大括号而不是引号,因此发送的是字符和,而不是回车符send{enable\r}
- 您从
返回0和1,就像您是一个shell程序员一样(这不是侮辱,我也是)。改用Tcl的布尔值connect
#!/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"
}
#/usr/bin/expect-f
设置提示“prompt>”
进程连接{passw}{
预期“assword:”
发送“$passw\r”
期待{
$::提示{返回真值}
超时{返回错误}
}
}
lassign$argv用户密码主机
#检查是否提供了所有信息
如果{$user==“”| |$passw==“”| |$host==“”}{
放置“用法:[信息脚本]”
出口1
}
spawn ssh-oStrictHostKeyChecking=no-oCheckHostIP=no$user@$host
如果{[connect$passw]}{
发送“启用\r\n”
预期$::提示
发送“显示正在运行\r\n”
预期$::提示
发送“退出\r”#整齐地关闭会话
预期eof
}否则{
放置“\n连接到交换机时出错:$host,用户:$user!\n”
}
不是答案(因此是注释),但您可能想看看rancid()是如何做到这一点的。spawn\u id是全局的,expect使用了与Tcl不同的作用域机制:您不应该显式地将spawn\u id传递给proc。是的,Glenn。对的我这样做是为了避免任何可能的问题,比如脚本中使用了多个繁殖