2009-08-19 70 views
2

我做了一个Bash脚本,它使用期望脚本来自动执行ssh登录。该脚本连接到多个服务器并运行一些命令。 bash脚本提示输入一次登录凭证。从Bash调用的Expect脚本的退出状态代码

我想加入一个功能,其中脚本在第一台服务器登录失败时终止,以避免脚本检查下一台服务器导致用户帐户被锁定。帐户锁定发生3次连续登录失败,脚本尝试连接的服务器数量超过3个。

这是调用期望脚本的bash脚本中的代码片段。

countu=0 
for servername in $(cat $linux_host_list) 
do 
./script.expect $LUSERNAME $LPASS $servername Linux >> linux_log_file.txt & < /dev/null 
let countl=countl+1 
done 

这里是期待脚本(script.expect)片断

#!/usr/bin/expect -f 
set timeout 30 
set username [lindex $argv 0] 
set SPASS [lindex $argv 1] 
set servername [lindex $argv 2] 
set case [lindex $argv 3] 
set prompt "(%|#|\\$|%\]) $" 
switch $case { 
    Linux { 
     log_user 0 
     spawn ssh -o StrictHostKeyChecking=no [email protected]$servername 
     expect { 
      "assword:" { 
       send "$SPASS\r" 
       expect -re "$prompt" 
      } 
      expect -re "$prompt" 
     } 
     send "sudo su -\r" 
     expect { 
      "assword:" { send "$SPASS\r" } 
     } 
     expect -re "$prompt" 
     log_user 1 
     send "opcagt -status ; opctemplate -l ; cat watch.cf 2> /dev/null\r" 
     expect -re "$prompt" 
     log_user 0 
     send "exit\r" 
     expect -re "$prompt" 
     log_user 1 
    } 

我试图抓住bash命令输出($?)假设,如果登录不正确的失败bash命令将返回一个非零值期望脚本中的密码,但没有解决。 任何建议将不胜感激。

回答

1

你应该认真看看Fabric

+3

老实说,我会犹豫移动到任何超过预期。多年来,Expect一直是实现自动化系统任务自动化的重要工具之一。它做了很多其他这样的工具无法比拟的东西(例如它几乎完美地模拟tty /用户的能力)。这并不是说布料不是很好,因为我对它一无所知......只是这个Expect有一些很大的鞋子可以填充。 – RHSeeger 2009-08-20 20:13:13

+1

我只是建议这是因为Fabric只是为了这样的任务而制作的。无害! – iElectric 2009-08-25 10:44:45

+0

面料看起来很酷,感谢分享。 – 2010-08-23 22:35:15

0

我倒没为脚本和所有的,因此,我不能写的具体步骤或脚本来证明什么,我记了 - 敬请原谅

嗯,我读了庆典提供了一个被称为退出状态的东西

退出状态是0是真实状态和1或其他任何虚假

你可以通过执行一个命令,然后键入检查其退出状态看这个“回声$?”

我的建议是,当你尝试ssh到一台服务器和身份验证失败,应当有其他比0

这里获得一个if-then-else的循环和检查状态为0东西的退出状态脚本的执行,任何其他值与相应的错误信息

+0

如果您阅读我的问题,我说我已经尝试过($?)但是没有成功。 – Sharjeel 2009-08-20 08:23:51

2

对于错误的expect脚本检查完全退出脚本,有一个在http://systeminetwork.com/article/handle-errors-expect-scripts

一个体面的例子你应该做的是这样的:

proc do_exit {msg} { 
    puts stderr $msg 
    exit 1 
} 

switch -exact -- $case { 
    Linux { 
     spawn ssh ... 
     expect { 
      -re {assword: $} { 
       send -- "$SPASS\r" 
       exp_continue 
       # remain in this expect block and look for the next matching pattern 
      } 
      "some message about incorrect password" { 
       do_exit "incorrect password" 
      } 
      timeout {do_exit "timed out waiting for prompt"} 
      default {do_exit "something else happened"} 
      -re $prompt 
     } 
     # ... rest of your script 
    } 
} 

我假设您不需要知道“opcagt ...”系列命令的退出状态(您只想查看watch.cf文件的内容。如果你做护理,你需要得到shell来告诉你:

send -- "opcagt -status 2>&1 || echo "non-zero return from opcagt: $?" 
expect { 
    "non-zero return" { handle error and exit? } 
    -re $prompt 
} 
# ... continue 
0

你在后台(&)运行预期脚本,所以你不能拥有的第一个结果然后继续。

您期望的脚本写入的方式,如果第一次输入密码失败,它将在第二次密码提示中获得30秒的超时时间。相反,你可以做一个expect替代方案,看看你是否得到另一个assword提示,并立即退出。

然后将shell脚本更改为不将期望调用置于后台,而是使用$?捕获输出并对其进行测试。

1

的部分:

expect { 
     "assword:" { 
      send "$SPASS\r" 
      expect -re "$prompt" 
     } 
     expect -re "$prompt" 
    } 

看起来非常可疑给我。特别是,我真的希望这会让事情变得困惑。一个更习惯写作的方式是:

expect { 
     "assword:" { 
      send "$SPASS\r" 
      exp_continue 
     } 
     -re "$prompt" 
    }