Search code examples
iosbashexpectcisco

Updating IOS's via SCP in bash with expect


Good day. I am attempting to create/run a script that will allow me to send an updated IOS from a server to my network devices. The following code works when I put in a manual IP address right before the ":flash" command.

 #!/user/bin/expect
 set IOSroot "/xxxxx/xxx/c3750e-universalk9-mz.150-2.SE10a.bin"
 set pw xxxxxxxxxxxxxxxxxxx

 spawn scp $IOSroot 1.1.1.1:flash:/c3750e-universalk9-mz.150-2.SE10a.bin

 expect "TACACS Password:"
 send "$pw\r"
 interact

The code there works great and as expected. The issue arises when I try to use a file called "ioshost" with a list of IP's and use that within this script to get some automation. I have tried various things to get this to work. Some of them are as follows:

Settings Variables

IPHosts=$(cat ioshost)

set IPHost 'cat ioshost'

Along with trying to use the read/do command...

while read line; do
spawn scp $IOSroot $line:flash:/c3750e-universalk9-mz.150-2.SE10a.bin
done < ioshost

None of these seem to work and I am looking for guidance. Please note I understand that setting a password is not best practice but setting RSA keys as mentioned in other articles is not allowed so I am forced to do it this way.

Thank you for your time.


Solution

  • You can use one Expect script and one Bash script.

    First update your Expect script a bit:

    #!/user/bin/expect
    set IOSroot "/xxxxx/xxx/c3750e-universalk9-mz.150-2.SE10a.bin"
    set pw xxxxxxxxxxxxxxxxxxx
    
    spawn scp $IOSroot [lindex $argv 0]:flash:/c3750e-universalk9-mz.150-2.SE10a.bin
    #                  ^^^^^^^^^^^^^^^^
    
    expect "TACACS Password:"
    send "$pw\r"
    interact
    

    Then write a simple Bash for loop:

    for host in $(<ioshost); do
        expect /your/script.exp $host
    done