Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Using Expect and trying to Extract a cisco router hostname to a variable

762 views
Skip to first unread message

netwrkgeek

unread,
Sep 10, 2009, 11:50:15 AM9/10/09
to
Greetings,

I have written script which accepts input from a user/administrator
and backs up the startup config of a range of Cisco switches by
telnetting in, enabling, writes to mem, then copies the startup config
file via tftp to our nms server, exits the switch, then moves to the
next switch until done. The Script names the backed up file by the
last two octets of the IP address and appends the date and time it is
backed up. I am trying to add in a way to append the hostname to the
file instead of the last two octets of the IP address. This will make
the files more human-readable when perusing the directory where they
are stored in case of a recovery.
I have include the code Snippet and the whole script.

Any help would be appreciated, Thanks.

This is what I have:

########## Begin Code Snippet #####################

send "show run | include hostname\n" ### This returns the hostname ###
expect -re "(.*)\n" {set hn $expect_out(1,string}
send "$hn-gotit\n"
send "copy startup-config tftp:\n"
send "192.168.111.82\n"
send "$ip.$i-cisco-switch-cfg\_$month\_$day\_$year\n

######### End Code Snippet #################


############## Whole Script
##############################################
send_user "Enter the third octet of the IP addresses of the switches
you want to backup: "
stty echo
expect_user -re "(.*)\n" {set ip $expect_out(1,string)}
send_user "\n"
stty echo

send_user "Enter the the last octet of the first switch you want to
backup: "
stty echo
expect_user -re "(.*)\n" {set j $expect_out(1,string)}
send_user "\n"
stty echo

send_user "Enter the last octet of the last switch you wish to
backup: "
stty echo
expect_user -re "(.*)\n" {set k $expect_out(1,string)}
send_user "\n"
stty echo


for {set i $j} {$i <= $k} {incr i} {

spawn ping 153.18.$ip.$i -c 2
expect "100%" {set to 0} "0%" {set to 1}
send_user "$to\n"

if { $to == 1} {

set now [clock seconds]
set then [clock format $now -format %T]
send_user "$then\n"
set month [timestamp -format %m]
set day [timestamp -format %d]
set year [timestamp -format %Y]
send_user "$month\_$day\_$year\_at\_$then\n"
spawn -noecho telnet 153.18.$ip.$i
expect -re "Password"
send "$pw\n"
send "enable\n"
send "$enpw\n"
send "write mem\n"
set hn [send "show run | include hostname\n"]
expect -re "(.*)\n" {set hn $expect_out(1,string}
send "$hn-gotit\n"
send "copy startup-config tftp:\n"
send "153.18.111.82\n"
send "$ip.$i-cisco-switch-cfg\_$month\_$day\_$year\n"
send " exit\n"
interact

} else {
continue
}
}

################## End Whole script
####################################################

Patrick

unread,
Sep 10, 2009, 3:00:12 PM9/10/09
to
Assuming hn properly has the hostname, wouldn't your send command just
be

send "$hn.$i-cisco-switch-cfg\_$month\_$day\_$year\n

I think I am missing something. If so can you be more specific in your
question?

netwrkgeek

unread,
Sep 10, 2009, 3:50:47 PM9/10/09
to
Patrick,

That is the goal, I can read the hostname using this line:

send "show run | include hostname\n"

This returns: 'hostname 3750G-Bldg1'

The trick is extracting the pattern minus 'hostname' and including the
real hostname
ie. '3750G-Bldg1' and having it stored in the variable '$hn'

This line here:

send "$hn-gotit\n"

is a test to see if I am even getting to that point but it never gets
there.

The script breaks down after this line:

expect -re "(.*)\n" {set hn $expect_out(1,string}

Thanks for getting back.
Hope that is clearer.

On Sep 10, 12:00 pm, Patrick <patrick.dunni...@activecompliance.com>
wrote:

> > ######### End Code Snippet #################- Hide quoted text -
>
> - Show quoted text -

Gerald W. Lester

unread,
Sep 10, 2009, 6:40:40 PM9/10/09
to
netwrkgeek wrote:
> Patrick,
>
> That is the goal, I can read the hostname using this line:
>
> send "show run | include hostname\n"
>
> This returns: 'hostname 3750G-Bldg1'
>
> The trick is extracting the pattern minus 'hostname' and including the
> real hostname
> ie. '3750G-Bldg1' and having it stored in the variable '$hn'

Well, you could get the entire string, then use:
set hn [string range $line 9 end]
instead of a regular expression (*everything* does not have to be done using
regular epressions).

> This line here:
>
> send "$hn-gotit\n"
>
> is a test to see if I am even getting to that point but it never gets
> there.
>
> The script breaks down after this line:
>
> expect -re "(.*)\n" {set hn $expect_out(1,string}

If that line is really what is in the script, I'd expect it to break. You
are missing the closing parenthesis on the array reference (looking at the
original post, there are a couple of spots with the same error).


--
+------------------------------------------------------------------------+
| Gerald W. Lester |
|"The man who fights for his ideals is the man who is alive." - Cervantes|
+------------------------------------------------------------------------+

Uwe Klein

unread,
Sep 11, 2009, 3:54:52 AM9/11/09
to
Gerald W. Lester wrote:
> netwrkgeek wrote:
>
>> Patrick,
>>
>> That is the goal, I can read the hostname using this line:
>>
>> send "show run | include hostname\n"
>>
>> This returns: 'hostname 3750G-Bldg1'
>>
>> The trick is extracting the pattern minus 'hostname' and including the
>> real hostname
>> ie. '3750G-Bldg1' and having it stored in the variable '$hn'
>
>
> Well, you could get the entire string, then use:
> set hn [string range $line 9 end]
> instead of a regular expression (*everything* does not have to be done
> using regular epressions).
>
>> This line here:
>>
>> send "$hn-gotit\n"
>>
>> is a test to see if I am even getting to that point but it never gets
>> there.
>>
>> The script breaks down after this line:
>>
>> expect -re "(.*)\n" {set hn $expect_out(1,string}
>
>
> If that line is really what is in the script, I'd expect it to break.
> You are missing the closing parenthesis on the array reference (looking
> at the original post, there are a couple of spots with the same error).
>
>

aditionally expecting -re ".*" does not do what one would expect.
( i.e. it expects all characters available _at that time_
which may be empty.
n8k should anchor his regular expression:


expect -re {hostname ([^\s]*)} {
# the complete re is in :
puts out0:$expect_out(0,string)
# the subexpression () is in:
puts out1:$expect_out(1,string)
} timeout {
puts timeout
# for diagnostics we flush all input into expect_out(*)
expect -re .*
parray expect_out
}

uwe

0 new messages