我正在尝试创建一个期望脚本以非交互方式更新用户的密码。新功能和shell脚本。我希望能够捕获和处理遇到的错误。例如,如果我正常运行passwd,并且由于某种原因我的新密码不被接受,我可能会看到类似“密码错误:密码与旧密码太相似”的信息。问题在于,在期望脚本中,使用无效的密码发送$ new_pswd \ r后,期望“错误密码:*”失败,因为passwd的下一个输出是“”。我想捕获错误的密码和消息,以便可以将它们返回给调用过程。这里的用例是允许拥有多个帐户的单个用户一次性使用相同的密码更新所有帐户。每个帐户都会调用一次此脚本。
#!/usr/bin/expect -df
# THIS SCRIPT WON'T WORK
set old_pswd $::env(PSWD1)
set new_pswd $::env(PSWD2)
spawn passwd
expect "*ssword:" { send "$old_pswd\r" }
expect "*ssword:" { send "$new_pswd\r" }
expect {
"*ssword:" {
puts "Expected\r"
send "$new_pswd\r"
exit 0
}
"BAD PASSWORD:*" {
puts "BAD PASSWORD\r"
send \x03
exit 1
}
"*" {
puts "Unexpected\r"
send \x03
puts $expect_out(buffer)
exit 1
}
}
更新:从昨天开始,我学到了很多关于期望的知识,并最终解决了该问题以及脚本中的其他几个问题。第一个问题是我期望密码提示在冒号后没有空格,因此所有后续的Expect命令都试图与尚未使用的空格字符匹配,后者与“ *”匹配,并在passwd之前终止了脚本曾经发送过错误密码消息。第二个问题是尝试将* ssword:匹配到“密码错误”之前。输入新密码的提示将始终与错误密码消息之前匹配,因为passwd正在发送“错误密码:消息消息message \ r \ n新密码:”这是一个现在可以工作并被打包在su中的脚本。无论调用此脚本的任何过程,之后都需要清理环境变量。这样做的想法是预先安全地设置这些凭据,以便不必在命令行上传递凭据。该脚本旨在从用户帐户中为属于他们的每个其他帐户调用一次:
#!/usr/bin/expect -f
# THIS SCRIPT WORKS
set old_pswd $::env(PSWD1)
set new_pswd $::env(PSWD2)
set new_user $::env(USER1)
spawn su $new_user
expect "*ssword: " { send "$old_pswd\r" }
expect "$ " { send "passwd\r" }
expect "*ssword: " { send "$old_pswd\r" }
expect "*ssword: " { send "$new_pswd\r" }
expect {
"BAD PASSWORD: " {
expect {
"dictionary" { set exit_code 1 }
"shorter than" { set exit_code 2 }
"too similar" { set exit_code 3 }
"No password" { set exit_code 4 }
"*" { set exit_code 99 }
}
send \x03
expect "$ " { send "exit\r" }
exit $exit_code
}
"*ssword: " {
send "$new_pswd\r"
expect "$ " { send "exit\r" }
exit 0
}
}