我创建了一个Bash脚本,该脚本使用expect脚本自动执行ssh登录。该脚本连接到多个服务器并运行一些命令。 bash脚本会提示输入一次登录凭据。
我想要合并一个功能,如果第一台服务器登录失败,脚本会终止,以避免脚本检查下一台服务器导致用户帐户被锁定。帐户锁定连续3次登录失败,脚本尝试连接的服务器数量超过3。
这是调用expect脚本的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 $username@$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命令输出($?
),假设如果在expect脚本中登录失败,但是没有用,则bash命令将返回非零值。
任何建议都会非常感激。
答案 0 :(得分:2)
对于期望脚本中的错误检查,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
答案 1 :(得分:1)
你应该认真看看Fabric。
答案 2 :(得分:1)
部分:
expect {
"assword:" {
send "$SPASS\r"
expect -re "$prompt"
}
expect -re "$prompt"
}
对我来说非常可疑。特别是,我真的希望这会让事情变得混乱。更惯用的写作方式是:
expect {
"assword:" {
send "$SPASS\r"
exp_continue
}
-re "$prompt"
}
答案 3 :(得分:0)
我对脚本编写并不多,因此我无法编写确切的步骤或脚本来证明我的想法 - 请原谅
好吧,我读到bash提供了一个称为退出状态的东西
对于true,退出状态为0,对于false
,退出状态为1或其他任何状态您可以通过执行命令然后键入“echo $?”
来检查其退出状态我建议当你尝试ssh到一个服务器并且身份验证失败时,应该有一个非0的退出状态
在此处获取if-then-else循环并检查状态为0以执行脚本和任何其他值以完全退出脚本并显示相应的错误消息
答案 4 :(得分:0)
您正在后台运行期望脚本(&
),因此在继续之前您无法获得第一个结果。
编写期望脚本的方式,如果第一个密码失败,它将在第二个密码提示时获得30秒超时。相反,您可以执行expect
替代,以查看是否收到另一个assword
提示,然后立即退出。
然后更改shell脚本,不将期望调用放在后台,而是使用$?
捕获输出并进行测试。