Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用SSH和Expect连接到交换机_Ssh_Tcl_Expect - Fatal编程技术网

使用SSH和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

我是一个新手(尽管有很多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
#/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}
    ——由于使用大括号而不是引号,因此发送的是字符和,而不是回车符
  • 您从
    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"
}
#/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。对的我这样做是为了避免任何可能的问题,比如脚本中使用了多个繁殖