期望脚本+期望错过发送string+延迟问题

我写了active.ksh脚本(基于期望),以便自动login到一些Solaris机器并执行hostname命令(login到虚拟IP为了validation哪个主机名是活动的机器 – 我有两个群集solaris机器)

问题在于expect ; 期望发送密码string(pass123)而忽略密码问题,而仍然等待密码。

所以实际上密码问题后input密码(pass123)。 在大多数情况下,期望的脚本工作正常,但有时却错过了密码。

问题的例子

  ./active.ksh spawn ssh 10.10.18.61 sh: /usr/local/bin/stty: not found This computer system, including all related equipment, networks and network devices (specifically including Internet access),is provided only for authorized uss Password: * my remark - pass123 string was missed the Password Question pass123 Password: 

剧本

  #!/bin/ksh VIP_ADDRESS=10.10.18.61 expect_for_verify_which_active_machine=`cat << EOF set timeout -1 spawn ssh $VIP_ADDRESS expect { ")?" { send "yes\r" ; exp_continue } Password: {send "pass123\r"} } expect > {send "hostname\r"} expect > {send exit\r} expect eof EOF` expect -c "$expect_for_verify_which_active_machine" 

正确结果的例子

  ./active.ksh [Friday, February 24, 2012 2:32:06 PM IST] INFO Verify which is active SMU machine spawn ssh 10.10.18.61 sh: /usr/local/bin/stty: not found This computer system, including all related equipment, networks and network devices (specifically including Internet access),is provided only for authorized uss yes Password: Last login: Fri Feb 24 14:32:06 2012 from smu1a This computer system, including all related equipment, networks and network devices (specifically including Internet access),is provided only for authorized uss solaris1:/ ROOT > hostname solaris1 solaris1:/ ROOT > exit logout Connection to 10.10.18.61 closed. 

如果您在login时监控string,您将希望避免使用“密码:”,您会发现它并不总是大写。

改变你的期望 – -re "(.*)assword:""assword:"往往是更有效的捕捉线。

如果你发现时间太快,你可以睡一会儿; 在你发送之前

这是我所期望的

 expect { "(yes/no)?" { send "yes\n" } "passphrase" { send "\r" } -re "(.*)assword:" { sleep 1; send -- "password\r" } -re $prompt { return } timeout { puts "un-able to login: timeout\n"; return } eof { puts "Closed\n" ; return } } 

我不清楚你为什么使用expect 。 既然你有SSH访问远程主机,最简单的解决scheme将是明确build立ssh 公钥authentication为此目的; 那么你可以简单地运行…

 ssh 10.10.18.61 hostname 

…一切都会正常工作*。 即使使用expect你做了太多的工作,因为即使使用密码authentication,你可以发出上述命令,而不必担心使用expect与远程shell进行交互。 你会发送类似的东西:

 #!/bin/sh VIP_ADDRESS=10.10.18.61 expect <<EOF spawn ssh $VIP_ADDRESS hostname expect Password: send "pass123\n" expect eof EOF 

就是这样。

您可以使用-d标志debugging您的期望脚本。 在我的情况下,以debugging模式运行的上述期望脚本的输出包括以下内容:

 expect: does "" (spawn_id exp4) match glob pattern "password:"? no lars@localhost's password: expect: does "lars@localhost's password: " (spawn_id exp4) match glob pattern "password:"? yes expect: set expect_out(0,string) "password:" expect: set expect_out(spawn_id) "exp4" expect: set expect_out(buffer) "lars@localhost's password:" send: sending "PASSWORD\n" to { exp4 } myhost.example.com expect: read eof expect: set expect_out(spawn_id) "exp4" expect: set expect_out(buffer) " \r\nobliquity.int.seas.harvard.edu\r\n" 

这显示了expect匹配和发送的内容。

*技术上你可能不得不解决一些主机关键问题,但这很容易。