From: Matt Z. <mzagrabe@d.umn.edu> - 2007-11-15 14:50:19
|
On Wed, 2007-11-14 at 17:58 -0600, Noah wrote: > Matt, >=20 > I am not doing something correct here. No, I am not doing something correct. I mistakenly sent you code snippets that made use of Net::Telnet. Here is a little more complete set of code, note that I may have missed copying something from my source files. Nevertheless, you will get the idea. my $found_prompt =3D undef; my $text_io =3D ''; my $exp =3D &log_in_to_infrastructure($configs, $infrastructure, \$text_io, \$found_prompt, $command); # process text_io here if you want. if ($found_prompt) { $found_prompt =3D undef; $text_io =3D ''; &send_and_receive($configs, "show interfaces status\n", \$text_io, $exp, \$found_prompt); # process text_io here } sub send_and_receive { my $configs =3D shift; my $send_string =3D shift; my $receive_buffer =3D shift; my $expect_object =3D shift; my $wait_for_found =3D shift; my $more_output =3D (@_) ? shift : '--More--'; my $continue_command =3D (@_) ? shift : ' '; my $wait_for =3D (@_) ? shift : '>$'; # set up logging the output to the buffer if ($receive_buffer ne undef) { $expect_object->log_file(sub { $$receive_buffer .=3D shift;}); } =20 # send the string $expect_object->send($send_string); # dont stop logging until we have seen the $wait_for $expect_object->expect($configs->{'management_timeout'}, [ qr/$more_output/i, sub {my $self =3D shift; $self->send($continue_command); exp_continue;}], # 1924 specific prompt [ qr/\[X\] Exit.*:/ism, sub { $$wait_for_found =3D 1; undef;}], # user defined prompt [ qr/$wait_for/i, sub { $$wait_for_found =3D 1; undef;}]); } sub log_in_to_infrastructure { my $configs =3D shift; my $infrastructure =3D shift; my $receive_buffer =3D shift; my $wait_for_found =3D shift; my $command =3D (@_) ? shift : 'telnet'; my $use_menu_1924 =3D (@_) ? shift : undef; my $wait_for =3D (@_) ? shift : '>$'; my $username =3D (@_) ? shift : $configs->{'management_user'}; my $password =3D (@_) ? shift : $configs->{'management_password'}; if ($command eq 'ssh') { $command =3D '/usr/bin/ssh -l '.$username.' '; } else { $command =3D '/usr/bin/telnet '; } my $exp =3D new Expect; $exp->slave->stty(qw(raw -echo)); my $exp =3D Expect->spawn("$command $infrastructure") or die "Cannot spawn $command: $!\n"; $exp->log_stdout(0); if ($receive_buffer ne undef) { $exp->log_file(sub { $$receive_buffer .=3D shift;}); } # note retval is currently unused my $retval =3D $exp->expect($configs->{'management_timeout'}, [ qr/user(name)?: /i, sub { my $self =3D shift; $self->send("$username\n"); exp_continue;}], [ qr/password:\s*/i, sub { my $self =3D shift; $self->send("$password\n"); exp_continue;}], [ qr/Catalyst 1900 Management Console.*Enter Selection: /ism, sub { my $self =3D shift; $self->send($use_menu_1924 ? 'm' : 'k'); exp_continue;}], [ qr/\[X\] Exit Management Console.*Enter Selection:/ism, sub { $$wait_for_found =3D 1; undef;}], # if first time ssh'ing to a infrastructure, then accept # the public key [ qr/\(yes\/no\)\?/i, sub { my $self =3D shift; $self->send("yes\n"); exp_continue;}], [ qr/$wait_for/i, sub { $$wait_for_found =3D 1; undef;}]); return $exp; } > I run my script and get the following: > "Can't call method "put" on an undefined value at ./maintenance.check.pl=20 > line 96." >=20 > Cheers, >=20 > Noah >=20 >=20 > Matt Zagrabelny wrote: > > On Wed, 2007-11-14 at 15:39 -0600, Noah wrote: > >=20 > > [...] > >=20 > >> is there a way to capture the output with perl-expect into an array? > >=20 > > Here are some snippets of what I have done in the past, though I do > > things a little differently now, you will get the idea... hopefully. ;) > >=20 > > Subroutine to send a command to Cisco devices and capture the output in > > the scalar reference $receive_buffer. > >=20 > > sub send_and_receive { > > my $configs =3D shift; > > my $send_string =3D shift; > > my $receive_buffer =3D shift; > > my $command =3D shift; > > my $wait_for_found =3D (@_) ? shift : undef; > > my $more_output =3D (@_) ? shift : '--More--'; > > my $continue_command =3D (@_) ? shift : " ";=20 > > my $wait_for =3D (@_) ? shift : '>$'; > > =20 > > # send whatever it is we are to send > > $command->put($send_string); > >=20 > > # now wait for the "wait_for" meanwhile saving > > # all the output into receive_buffer > > my $done =3D undef; > > until ($done) { > > my ($prematch, $match) =3D (undef, undef); > > ($prematch, $match) =3D > > $command->waitfor(Match =3D> '/'.$more_output.'/i', > > Match =3D> '/'.$wait_for.'/i', > > Match =3D> '/\\[X\\] Exit.*:/ism', > > Timeout =3D> $configs->{management_timeout}); > >=20 > > if ($receive_buffer ne undef) { > > $$receive_buffer .=3D $prematch.$match; > > } =20 > >=20 > > if ($match =3D~ /$more_output/i) { > > $command->put($continue_command); > > } elsif ($match =3D~ /$wait_for/) { > > $$wait_for_found =3D 1 if ($wait_for_found); > > $done =3D 1;=20 > > } elsif ($match =3D~ /\[X\] Exit.*:/ism) { > > $$wait_for_found =3D 1 if ($wait_for_found); > > $done =3D 1;=20 > > } =20 > > } > > } > >=20 > > $text_io =3D ''; > > &send_and_receive($configs, > > "show interface status\n", > > \$text_io, > > $connection, > > \$found_prompt); > >=20 > > my @lines =3D split /\n/, $text_io; > > for (@lines) { > > $_ =3D &trim($_); > > } > >=20 > > sub trim { > > my $s =3D shift; > > $s =3D~ s/^\s*//; > > $s =3D~ s/\s*$//; > > return $s; > > } =20 > >=20 [...] --=20 Matt Zagrabelny - mzagrabe@d.umn.edu - (218) 726 8844 University of Minnesota Duluth Information Technology Systems & Services PGP key 1024D/84E22DA2 2005-11-07 Fingerprint: 78F9 18B3 EF58 56F5 FC85 C5CA 53E7 887F 84E2 2DA2 He is not a fool who gives up what he cannot keep to gain what he cannot lose. -Jim Elliot |