期望脚本 + 期望错过发送字符串 + 延迟问题

期望脚本 + 期望错过发送字符串 + 延迟问题

我编写了 active.ksh 脚本(基于 expect),以便自动登录到某些 Solaris 机器并执行 hostname 命令(登录到虚拟 IP 以验证哪个主机名是活动机器 - 我有两台集群 solaris 机器)

问题在于expect;expect 发送密码字符串 (pass123) 并且它错过了密码问题,并且它仍然等待密码。

因此,实际上密码 (pass123) 是在密码问题之后输入的。在大多数情况下,expect 脚本工作正常,但有时它会错过密码。

问题示例

 ./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.

答案1

如果您在登录期间监视字符串,您将需要避免使用“密码:”,您会发现它并不总是大写的。

改变您的期望-re "(.*)assword:""assword:"往往会更有效地赶上潮流。

如果你发现时间还是太快,你可以在发送之前添加 sleep 1;

这是我期望使用的

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

答案2

我完全不明白你为什么要使用expect。由于你可以通过 ssh 访问远程主机,最简单的解决方案就是建立 ssh公钥认证明确为此目的;然后您可以简单地运行......

ssh 10.10.18.61 hostname

...一切都会正常工作*。即使使用,expect您也做了太多工作,因为即使使用密码验证,您也可以发出上述命令,而不必担心使用 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标志调试你的期望脚本。在我的例子中,在调试模式下运行的上述期望脚本的输出包括以下内容:

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匹配的内容和发送的内容。

* 从技术上讲,您可能必须解决一些主机密钥问题,但这很容易。

相关内容