So recently I have been working on a small script that will login to a remote unix host and change its password, I've never had much experience with expect so its been an upward learning curve.

The script I have so far is this:


#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"}

The idea is this will automate a small process, but the script runs down to where it successfully logs into the system and then offers nothing, doesn't continue to the password reset so essentially stops after it ssh's.

UPDATE: Managed to get past the blank line issue by using "send -- "\r"" before it runs the password reset command. The script now runs to completion but it clearly enters an incorrect password on the second confirmation. Have added the output below:

::> ssh connection succeeded
::> security login password -username ######

Enter a new password:
Enter it again:

Error: Passwords didn't match.

password change successful for ######


First off thank you guys for your help so far, I switched the script over to debug mode and ran it again, as well as changing how the variables were set.

This is the output from the debug mode, as far as I can see the required passwords are both the same so I am unsure why they are failing.

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

Error: Passwords didn't match.

  • while developing an expect script, turn on debugging so you can see what's coming in and going out: add this to the top of your script exp_internal 1 or #!/usr/bin/expect -d or run it with expect -d script.exp Mar 20 '18 at 13:40
  • Add a short sleep 1; before each send after receiving the prompt for a password, as the remote may need time to switch echo off etc.
    – meuh
    Mar 20 '18 at 18:41

Not an answer, but a comment that needs formatting: The way you're getting the script's arguments is subtly wrong. lrange returns a list, and when you stringify a list some special characters are going to get escaped. This would affect the password you send. Do this instead:

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

Since you send the same possibly wrong password twice, I don't see why you're getting that error. Adding debugging may reveal the issue.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.