所以最近我一直在开发一个小脚本,它将登录到远程unix主机并更改其密码,我从来没有太多使用expect的经验,所以它是一个向上的学习曲线。
到目前为止我的脚本是这样的:
#!/usr/bin/expect
#Setting variables based on their location in the original script call
set username [lrange $argv 0 0]
set password [lrange $argv 1 1]
set server [lrange $argv 2 2]
set port [lrange $argv 3 3]
set changeuser [lrange $argv 4 4]
set newpassword [lrange $argv 5 5]
set yesval yes
set prompt "::>"
set timeout 60
spawn ssh -p $port $username@$server
match_max 100000
expect "yes/no" {
send "yes\r"
expect "*?assword" { send "$password\r" }
} "*?assword" { send "$password\r" }
expect "::>" {
send_user "ssh connection succeeded\n"
} "*?assword" { send_user "\nssh connection failed due to wrong password\n"; exit 2}
send -- "\r"
expect "::>" {send "security login password -username $changeuser\r "}
expect "Enter a new password:*" {send "$newpassword\r"}
expect "Enter it again:*" {send "$newpassword\r"}
expect "::>" {send "exit\r";send_user "\npassword change successful for $changeuser\n"}
expect "Enter a new password:*" { send "exit\r";send_user "\npassword change not successful for $changeuser\n"}
这个想法是,这将自动执行一个小过程,但脚本运行到成功登录系统的位置,然后不提供任何内容,不会继续重置密码,因此在 ssh 之后基本上停止。
更新:在运行密码重置命令之前,通过使用“send --“\r””设法解决了空行问题。该脚本现在运行完成,但在第二次确认时它显然输入了错误的密码。添加了以下输出:
::> ssh connection succeeded
::> security login password -username ######
Enter a new password:
Enter it again:
Error: Passwords didn't match.
::>
password change successful for ######
exit
Goodbye
更新2:
首先感谢大家迄今为止的帮助,我将脚本切换到调试模式并再次运行它,并更改了变量的设置方式。
这是调试模式的输出,据我所知,所需的密码都是相同的,所以我不确定它们为什么失败。
expect: set expect_out(0,string) "Enter a new password: "
expect: set expect_out(spawn_id) "exp5"
expect: set expect_out(buffer) " security login password -username user\r\n\r\nEnter a new password: "
send: sending "Passtest123\r" to { exp5 }
expect: does "" (spawn_id exp5) match glob pattern "Enter it again:*"? no
Enter it again:
expect: does "\r\nEnter it again: " (spawn_id exp5) match glob pattern "Enter it again:*"? yes
expect: set expect_out(0,string) "Enter it again: "
expect: set expect_out(spawn_id) "exp5"
expect: set expect_out(buffer) "\r\nEnter it again: "
send: sending "Passtest123\r" to { exp5 }
expect: does "" (spawn_id exp5) match glob pattern "Error: Passwords didn't match.*"? no
expect: does "\r\n" (spawn_id exp5) match glob pattern "Error: Passwords didn't match.*"? no
错误:密码不匹配。
答案1
不是答案,而是需要格式化的评论:您获取脚本参数的方式是微妙错误的。lrange
返回一个列表,当您对列表进行字符串化时,一些特殊字符将会被转义。这会影响您发送的密码。改为这样做:
set username [lindex $argv 0]
set password [lindex $argv 1]
set server [lindex $argv 2]
set port [lindex $argv 3]
set changeuser [lindex $argv 4]
set newpassword [lindex $argv 5]
或者
lassign $argv username password server port changeuser newpassword
由于您两次发送相同的可能错误的密码,我不明白为什么您会收到该错误。添加调试可能会揭示问题。