Reputation: 549
I'm in the process of changing the password of an account for about 400 servers. When I ssh into the server, two possible prompts may appear: if the account has been expired, it will indicated:
Password:
Warning: Your password has expired, please change it now.
New Password:
Or I'll get the a normal prompt.
-bash-4.4$
So I want to write an expect script so that if I get the normal bash prompt, my script will proceed into changing the password or if the account has expired, it will proceed and change the password as well. My if statement in my script is erroring out.
#!/bin/bash
echo "[DEBUG] INIT BASH"
CURRENT_PW="xxxxx"
NEW_PW="xxxxxx"
/opt/csw/bin/expect <(cat << EOF
spawn ssh -o StrictHostKeyChecking=no useradmin@xxxxx
expect "Password:"
send "$CURRENT_PW\r"
set PROMPT [ expect "New Password: "]
if { $PROMPT } {
send "$NEW_PW\r"
expect "Re-enter new Password: "
send "$NEW_PW\r"
exit
}
else
expect "$ "
send "passwd useradmin\r"
expect "New Password: "
send "$NEW_PW\r"
expect "Re-enter new Password: "
send "$NEW_PW\r"
expect "passwd: password successfully changed for useradmin"
send "exit\r"
interact
EOF
)
echo "[DEBUG] END BASH"
Here is the error.
Password:
Warning: Your password has expired, please change it now.
New Password: empty expression
in expression " "
(parsing expression " ")
invoked from within
"if { } {
send "xxxxxx\r"
expect "Re-enter new Password: "
send "xxxxxx\r"
exit
}"
(file "/dev/fd/63" line 7)
[DEBUG] END BASH
Upvotes: 0
Views: 718
Reputation: 1947
If you want to check for a non-empty password, you should use something like
if {$PASSWORD ne ""} {
...
}
or
if {![string equal $PASSWORD ""]} {
...
}
Upvotes: 0
Reputation: 137567
This is a use for expecting multiple things at once (and is indeed the banner case for it), which searches for two (or more) different strings and branches according to which one occurs first:
# Set up some obvious variables up here, of course...
spawn ssh -o StrictHostKeyChecking=no ${User}@${Host}
expect "Password:"
send ${CurrentPassword}\r
# This waits for *either* the instruction to change the password or the main prompt
expect {
"New Password: " {
# A password change has been forced during login
send ${NewPassword}\r
expect "Re-enter new Password: "
send ${NewPassword}\r
expect "$ "
}
"$ " {
# Initiate the password change
send "passwd ${User}\r"
expect "New Password: "
send ${NewPassword}\r
expect "Re-enter new Password: "
send ${NewPassword}\r
expect "passwd: password successfully changed for ${User}"
}
}
send "exit\r"
close
exit
In this case we're not using exp_continue
, which when used in the body script of an expect
causes the waiting for a string to be restarted. That's useful for those cases where you can optionally hit something when logging in (and means that expect
is able to work as sort of while
as well as a sort of if
).
Upvotes: 3
Reputation: 13252
It seems that the value of PROMPT
is the empty string.
You also have a problem with the formatting of the if
invocation: you can't have an unescaped newline between }
and else
, and you need a {
after else
to enclose the alternate script.
Upvotes: 0