using expect to log into devices
I have looked extensively on the web for an answer and cannot find one, so I come to you guys. I am not allowed to use modules in PERL or Python or I wouldn't have to do it this way. I have to do this all in Expect and I am a newbie at it. Also, maybe I'm having the Friday afternoon "I want to go home" mental block and the answer is right in front of my nose. I have a file with 1000s of devices and another file with a list of commands. The program issues all commands for a device and then moves on to the next one using nested loops. In the debug I see the "spawn_id expNN" (where NN is a number that, I believe is representative of the number of file descriptors used in the system) increment only when a device does not respond. As long as a device responds before the timeout period I see the expNN number does not increase. As soon as a device doesn't respond the expNN count goes up and I can't figure out why. Once I hit a certain expNN the program exits ungracefully; usually somewhere between 2500 and 3500 devices because our FD is set to 256 and that's how long it takes for 256 devices to not respond before the timeout period. Can anyone tell me why? Here is the relevant config snippet. I've tried every iteration of close and wait I found and no love... You'll want to put this into a fixed width font like Courier New or it'll just be a mess. foreach element $device { send_user "\n\n" send_user "#####################################\n" send_user "###### BEGIN $element #######\n" send_user "#####################################\n" spawn ssh -q -o StrictHostKeyChecking=no $username@$element expect { timeout { send_user "\nfailed to get password prompt\n\n" send_user "#####################################\n" send_user "####### END $element ########\n" send_user "#####################################\n" send_user "\n\n\n"; continue close $spawn_id wait } eof { send_user "\nssh failure for $element\n\n" send_user "#####################################\n" send_user "####### END $element ########\n" send_user "#####################################\n" send_user "\n\n\n"; continue close $spawn_id wait } "assword" { send "$password\n" } } expect { timeout { send_user "\npassword did not work or enable mode not achieved\n\n" send_user "#####################################\n" send_user "####### END $element ########\n" send_user "#####################################\n" send_user "\n\n\n"; continue close $spawn_id wait } eof { send_user "\npassword failure for $element\n\n" send_user "#####################################\n" send_user "######## END $element #########\n" send_user "#####################################\n" send_user "\n\n\n"; continue close $spawn_id wait } "" { send "term len 0\n" # send "skip-page-display\n" foreach command $commands { expect "#" send "$command\n" send_user "\n\n" } } } send "exit\n" send "exit\n" send_user "#####################################\n" send_user "####### END $element ########\n" send_user "#####################################\n" send_user "\n\n\n" close wait } Thanks! scott ps; I realize my indenting of the curly braces and other things are not standard... :)
Do you need to write this yourself, I've used this expect script too many times such that I should be ashamed...It "just works": https://sourceforge.net/projects/cosi-nms/files/ciscocmd/ Cheers, James.
On 7/20/18, Scott Weeks <surfer@mauigateway.com> wrote:
I have looked extensively on the web for an answer and cannot find one, so I come to you guys. I am not allowed to use modules in PERL or Python or I wouldn't have to do it this way. I have to do this all in Expect and I am a newbie at it.
Also, maybe I'm having the Friday afternoon "I want to go home" mental block and the answer is right in front of my nose.
I have a file with 1000s of devices and another file with a list of commands. The program issues all commands for a device and then moves on to the next one using nested loops. In the debug I see the "spawn_id expNN" (where NN is a number that, I believe is representative of the number of file descriptors used in the system) increment only when a device does not respond. As long as a device responds before the timeout period I see the expNN number does not increase. As soon as a device doesn't respond the expNN count goes up and I can't figure out why. Once I hit a certain expNN the program exits ungracefully; usually somewhere between 2500 and 3500 devices because our FD is set to 256 and that's how long it takes for 256 devices to not respond before the timeout period. Can anyone tell me why? Here is the relevant config snippet. I've tried every iteration of close and wait I found and no love...
'close $spawn_id' is wrong, so maybe that's it? man expect close [-slave] [-onexec 0|1] [-i spawn_id] closes the connection to the current process. ... The -i flag declares the process to close corresponding to the named spawn_id. <.. snip ..> No matter whether the connection is closed implicitly or explicitly, you should call wait to clear up the corresponding kernel process slot. close does not call wait since there is no guarantee that closing a process connection will cause it to exit. See wait below for more info. get rancid from here ftp://ftp.shrubbery.net/pub/rancid/ and take a look at clogin (which allows you to do 'clogin -x fileName dev1 dev2 ... devN' to run the commands in 'fileName' on the list of devices) The eof and timeout cases are basically { catch {close}; catch {wait}; } Regards, Lee
You'll want to put this into a fixed width font like Courier New or it'll just be a mess.
foreach element $device {
send_user "\n\n"
send_user "#####################################\n" send_user "###### BEGIN $element #######\n" send_user "#####################################\n"
spawn ssh -q -o StrictHostKeyChecking=no $username@$element
expect { timeout { send_user "\nfailed to get password prompt\n\n" send_user "#####################################\n" send_user "####### END $element ########\n" send_user "#####################################\n" send_user "\n\n\n"; continue close $spawn_id wait } eof { send_user "\nssh failure for $element\n\n" send_user "#####################################\n" send_user "####### END $element ########\n" send_user "#####################################\n" send_user "\n\n\n"; continue close $spawn_id wait } "assword" { send "$password\n" } }
expect { timeout { send_user "\npassword did not work or enable mode not achieved\n\n" send_user "#####################################\n" send_user "####### END $element ########\n" send_user "#####################################\n" send_user "\n\n\n"; continue close $spawn_id wait } eof { send_user "\npassword failure for $element\n\n" send_user "#####################################\n" send_user "######## END $element #########\n" send_user "#####################################\n" send_user "\n\n\n"; continue close $spawn_id wait } "" { send "term len 0\n" # send "skip-page-display\n"
foreach command $commands { expect "#" send "$command\n" send_user "\n\n" } } }
send "exit\n" send "exit\n"
send_user "#####################################\n" send_user "####### END $element ########\n" send_user "#####################################\n" send_user "\n\n\n"
close wait }
Thanks! scott
ps; I realize my indenting of the curly braces and other things are not standard... :)
participants (3)
-
James Bensley
-
Lee
-
Scott Weeks