0

Firstly I am asking this as a beginner in scripting, currently I have an expect script which automatically logs in to predefined Cisco devices and runs certain commands, I would like to update my script so that this same script can also backup Juniper devices.

Ideally what I would like the script to do is (in pseudo code)

      login / send credentials
      expect prompt
      send command "show version"
      if output contains "JUNOS" then
                send command 1
                send command 2
                send command 3
      otherwise if output contains "Cisco" then
                send command 1
                send command 2
                send command 3

Im sorry if this has been asked before, but I have tried searching and searching and couldn't find an answer if anyone can assist with this I would really appreciate it. I have also included my current expect script for your reference (this script gets called by a BASH Script)

set timeout 5
set hostname [lindex $argv 0]
set username "user"
set password "pass"

spawn ssh $username@$hostname

expect "Password:"
send "$password\n"
expect "#" {
send "terminal length 0\n"
send "show running-config\n"
expect "end\r"
send "\n"
send "exit\n"
}

---- UPDATE ---

Thanks for your input Dinesh - I have updated my script to include what you provided (as below)

set timeout 5
set hostname [lindex $argv 0]
set username "user"
set password "pass"
set prompt "(>|#|\\\$) $"

spawn ssh $username@$hostname


expect "*assword:"
send $password\r
send \r
expect -re $prompt {

    send "show version\r"
    expect -re $prompt
    expect *;

    set output $expect_out(buffer);

    #Basic string check logic with Tcl
    if { [string first "JUNOS" $output ]!=-1 } {
        send "show configuration | display set | no-more"
    expect -re $prompt
    send "exit\r"
    } else {
    send "terminal length 0\r"
    expect -re $prompt
    send "show run\r"
    expect "end"
    send \r
    expect -re $prompt
    send "exit\r"
    }
}

However when i run this script the issue I have is that the output of the "show version" doesn't seem to be matching my "string check" and the script therefore ignores the "if" statement and proceeds with the "else" statement.

The output of the "show version" command is below - what will I need to modify so that the "JUNOS" string gets matched?

user@host> show version
Hostname: host
Model: srx240h
JUNOS Software Release [11.4R7.5]

--- EDIT 2: Output from the script

05c4rw@testpc:~/script$ ./ssh.sh
spawn ssh user@juniperhost
## LOGIN BANNER - Removed for brevity

user@juniperhost's password:
--- JUNOS 11.4R7.5 built 2013-03-01 11:40:03 UTC
user@juniperhost> show version
Hostname: juniperhost
Model: srx240h
JUNOS Software Release [11.4R7.5]

user@juniperhost> show configuration | display set | no-more
set version 11.4R7.5

## *** OUTPUT REMOVED FOR BREVITY / PRIVACY ***

## *** END OF OUTPUT from previous command

 user@juniper> spawn ssh user@ciscohost
 password:
 ## LOGIN BANNER - removed for brevitiy

 ciscohost#05c4rw@testpc:~/script$
05c4rw
  • 1
  • 1
  • 1
  • 2
  • Place the code `expect *` before sending `show version` and print the value of `output`. Update the same here. – Dinesh Jan 13 '15 at 04:08
  • Hi Dinesh, thanks for that I have updated the configuration and now it is successfully running the "if" statement however the "else" statement doesn't appear to be working - as a test I have two devices in the list which it automatically logs in to the Juniper first and the Cisco after that - after successfully completing the Juniper part (if) it logs in to the Cisco Device and sits in the prompt before exiting (not issuing any commands) – 05c4rw Jan 13 '15 at 04:33
  • In that case, print the value of output (just to know for our convenience) and check what it contains before going to the `if-else` loop. – Dinesh Jan 13 '15 at 04:36
  • I've placed the output in the main question due to formatting issues, thanks. – 05c4rw Jan 13 '15 at 05:15
  • What I meant is to print the variable `output`'s value. The code can not skip the `if-else` loop. Code flow should either with `if` or `else` – Dinesh Jan 13 '15 at 08:03

2 Answers2

1
set timeout 5
set hostname [lindex $argv 0]
set username "user"
set password "pass"

spawn ssh $username@$hostname


expect "Password:"
send "$password\r"
expect "#" {

    send "terminal length 0\r"
    expect "#"
    # This is to clean up the previous expect_out(buffer) content
    # So that, we can get the exact output what we need.
    expect *;         
    send "show running-config\r"
    expect "end"

    #Now, the content of 'expect_out(buffer)' has the whole 'show run' output
    set output $expect_out(buffer);

    #Basic string check logic with Tcl  
    if { [string first "JUNOS" $output ]!=-1 } {
           # Apply your logic here
           # send "command1"
           # expect "#"
    } else {
           # Same as above        

           # I assume, there are 2 possibilities. So, keeping 'else' part alone.
           # Have 'else if', if you have more than 2.

    }
}

Notice that each line sent by the script is terminated with \r. This denotes a return character and is exactly what you would press if you entered these lines at the shell, so that is exactly what Expect has to send. It is a common mistake to terminate send commands to a process followed by \n. In this context, \n denotes a linefeed character. You do not interactively end lines with a linefeed. So Expect must not either. So, always use \r.

You can have a look at here if you are interested to know more about the why you need expect *. (which is a separate story)

I can see that there are some commands used only with send in your example. Basically, expect will work with two feasible commands such as send and expect. In this case, if send is used, then it is mandatory to have expect (in most of the cases) afterwards. (while the vice-versa is not required to be mandatory)

This is because without that we will be missing out what is happening in the spawned process as expect will assume that you simply need to send one string value and not expecting anything else from the session.

Community
  • 1
  • 1
Dinesh
  • 16,014
  • 23
  • 80
  • 122
  • Thanks Dinesh for your in-depth response, I have updated my original question with the results due to character limits imposed for responses on here. – 05c4rw Jan 13 '15 at 03:32
0

This might not be what you were looking for but thought I will post it just in case.

You might want to look into something like Rancid instead of having those scripts. Rancid will not only backup your device configs, it will also provide you with a diff on the devices it is managing at pre-defined intervals (for e.g if you set the interval to 15 mins, rancid will login to your devices every 15 mins grab the configs, back them up and do a diff with the previous version and show you the diff)

RedDevil
  • 13
  • 3
  • @thanksd rancid is more of a tool rather than a code snipet. You can get more detailed info here http://www.shrubbery.net/rancid/ – RedDevil Jun 11 '16 at 21:57