我写了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匹配和发送的内容。
*技术上你可能不得不解决一些主机关键问题,但这很容易。