0

I am trying to change the password for a user on a bunch of linux based routers pulling IPs from a list. The iplist.txt is just a list of ips (one per line). This is the code I am trying to use:

    #!/usr/bin/expect
    set timeout 20
    #Edit for User
    set user username
    #Edit for Old Password
    set old oldpassword
    #Edit for New Password
    set new newpassword
    #get IP List from iplist.txt
    set f [open "/iplist.txt"]
    set hosts [split [read $f] "\n"]
    close $f

    foreach host $hosts {
            spawn -noecho ssh -q -o "StrictHostKeyChecking=no" $user@$host
            expect "assword:"
            send "$old\r"
            expect ">"
            send "user set $user password=$new\r"
            expect ">"
            send "quit\r"
            expect eof
            close
    }

Which works for the first ip on the list but send this error on the second:

    spawn_id: spawn id exp4 not open

I got it to work this way as I wanted:

#!/usr/bin/expect
set timeout 30
#Edit for User
set user user
#Edit for Old Password
set old oldpassword
#Edit for New Password
set new newpassword
#get IP List from iplist.txt
set f [open "/iplist.txt"]
set data [read $f]
close $f

foreach line [split $data \n] {
        if {$line eq {}} continue
        spawn -noecho ssh -q -o "StrictHostKeyChecking=no" $user@$line
        expect "assword:"
        send "$old\r"
        expect ">"
        send "user set $user password=$new\r"
        expect ">"
        send "\r"
        expect ">"
        send "quit\r"
        send "\r"
        expect eof
}

The next issue I run into is if the device doesn't have the old password or if the linux box cannot reach the device via ssh, it will error out with the same spawn id exp* not open when it gets to that IP and will not continue onto the next IP in the list. Is there anyway I can a statement that says if "assword:" comes up a second time to move onto next IP and if ">" comes up like its supposed to keep going with the script, then add a line after the spawn command that will move to the next IP in list if it doesn't receive the first expect "assword:"?

Any help would be appreciated. I am new to expect, but seems to be a really good tool for mass ssh processes in a script. Just having trouble tweaking it to not error out on 1 job instead of moving to next job upon error.

0
#!/usr/bin/expect
set timeout 30
#Edit for User
set user user
#Edit for Old Password
set old oldpassword
#Edit for New Password
set new newpassword
#get IP List from iplist.txt
set f [open "/iplist.txt"]
set data [read $f]
close $f

foreach line [split $data \n] {
        if {$line eq {}} continue
        spawn -noecho ssh -q -o "StrictHostKeyChecking=no" $user@$line
        expect {
                "assword:" {
                        send "$old\r"
                        expect {
                                "assword:" {
                                                close
                                                continue
                                                }}
                        expect {
                                "*" {
                                        send "user set $user password=$new\r"
                                        expect ">"
                                        send "quit\r"
                                        close
                                        continue
                                        }}}}
        expect {
                "*" {
                        close
                        continue
                        }}
        expect eof
}

Probably a bit dirty scripting, but it works. Now if I can figure out how to export successful, wrong password, and timeout logs so I know if any error-ed out.

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.