From: <db...@CT...> - 2003-10-03 20:21:21
|
>>> Note: A know B but doesn't know C - in another words, to get to C you have >>> to go through B. Yes.. well, I guess it depends on what you're trying to say behind the words. Remember that you're spawning ONE process (or should be). Once you've done that and successfully logged into A, you should INVOKE telnet client on A to get to B, so there's no more "spawning" (from a perl module perspective), as B and C have no clue what the heck SPAWN is.. they just know what telnet is. Just imagine that you are invoking telnet on the command line from host to host to host, and that's ultimately what expects doing with the single telnet session you spawned to A. Imagine it that way and you should be able to see enough of what's going on to know how to use expect and code it. Remember that each time you hop, the STDOUT and STDERR channels get lashed together, and become STDIN to the thing that created it (parent.) They all get lashed together like the Alaskan pipeline, all the way back to your original spawned process in your expect script. In this daisy-chain telnet example you're trying to do, it is the only STDIN that your script should be dealing with. I don't know if that's the understanding you need, or if I'm confusing you more. Bottom line, If you can do it from the command line, i.e., telnet from A to B to C and so forth, then so can expect. If you can't do it, then neither can expect. It's that simple. All expect does is provide a way to automate the steps. The only difference between opening a process in Perl vs. Expect is that perl (by itself) cannot open a bi-directional pipe to a process. I.e., it can do this open (TELNET, " telnet $HOSTA | "); which would allow you to read from the session, or you can do this: open (TELNET, "| telnet $HOSTA "); to write to the process, but you cannot do both at the same time like this: open (TELNET, "| telnet $HOSTB | "); that's where Expect can help. The telnet module is an alternative that also does this, but only for telnet. Can't spawn a chess program on the command line and interact with it using telnet module, but you can do it using Expect (for all you telnet.pm zealots out there, that's the difference) If you want to look at primitive code that represents this idea, then it would look something like this: use Expect; $HOSTA=xx.xx.xx.1; $HOSTB=xx.xx.xx.2; $HOSTC=xx.xx.xx.3; $username="abc"; $password="123"; #------------ # telnet to A #------------ my $exp = Expect->spawn("telnet $HOSTA") or die "Cannot spawn telnet: $! \n"; $timeout=20; expect($timeout, "login: "); $exp->send("$username\n"); expect($timeout, "password: "); $exp->send("$password\n"); $expect($timeout, '-re', "[%#>] $"); # $HOSTA prompt #------------ # telnet to B #------------ $exp->send("telnet $HOSTB\n"); expect($timeout, "login: "); $exp->send("$username\n"); expect($timeout, "password: "); $exp->send("$password\n"); $expect($timeout, '-re', "[%#>] $"); # $HOSTB prompt #------------ # telnet to C #------------ $exp->send("telnet $HOSTC\n"); expect($timeout, "login: "); $exp->send("$username\n"); expect($timeout, "password: "); $exp->send("$password\n"); $expect($timeout, '-re', "[%#>] $"); # $HOSTC prompt Braindead simple example, but you should get the idea. Do a perldoc on Expect.pm and print it out, go to staples and buy a binder, put it in there and carry it around / put it on your desk at work also. If you REALLY want to get nuts and rule the world with Expect, go out and buy Don Libes most excellent O'Reilly book. Tcl is such a simple language, that you would have no problem figuring enough of it out on the fly to literally use this book as a supercharged reference for the Perl module, that is, unless you're a Perl zealot and can't for religious reasons.. although the perl module is not 100% translation, it's close enough for government work (so the saying goes.) Anyways, hope this helps you man. Hailey Nguyen <Hai...@Su...> To: Chris Muth <mut...@mc...> Sent by: cc: Hailey Nguyen <Hai...@Su...>, exp...@li...urc exp...@li... eforge.net Subject: Re: [Expectperl-discuss] Nested telnet sessions using Expect.pm module 10/02/2003 04:11 PM Hi Chris, >>> First you will have to login to A. That involves what you have, plus >>> you will have to $exp->expect() for whatever telnet responds with when >>> it asks for the password. Then use a $exp->send() to send the password. >>> Then $exp->expect() for the prompt on A. Once you are logged into A, >>> use a $exp->send() to call telnet $B on A to login to B, $exp->expect() >>> for the password prompt, and then $exp->send() it. Once logged into B, >>> do the same to login to C, and the same for D, and the same for ... Still struggling with this. As soon as I logged into B from A I lose control of that session/connection. So $exp->send() won't do anything. Did you write something like this before. Can I have an example? Note: A know B but doesn't know C - in another words, to get to C you have to go through B. Thanks a million, Hailey >>>> >>>> Please show me how to do nested telnet sessions using Expect.pm module? >>>> >>>> 1- telnet to machine A >>>> 2- from A to mcahine B >>>> 3- from B to machine C >>>> >>>> ----- >>>> use Expect; >>>> >>>> my $exp = Expect->spawn("telnet $somehost") >>>> or die "Cannot spawn telnet: $!\n"; >>>> >>>> ... >>>> >>>> ----- >>>> Your help is greatly appreciated. Please reply directly to me since >>>> I am not on the alias. >>>> ------------------------------------------------------- This sf.net email is sponsored by:ThinkGeek Welcome to geek heaven. http://thinkgeek.com/sf _______________________________________________ Expectperl-discuss mailing list Exp...@li... https://lists.sourceforge.net/lists/listinfo/expectperl-discuss |
From: Hailey N. <Hai...@Su...> - 2003-10-03 20:56:33
|
Hi D. Basham, It's definitely very helpful. Chris Muth has sent me an example and I got my stuff to work with that. But your info is also a great help to me. Thanks, HAiley > > >>>> Note: A know B but doesn't know C - in another words, to get to C you > have >>>> to go through B. > > Yes.. well, I guess it depends on what you're trying to say behind the > words. Remember that you're spawning ONE process (or should be). Once > you've done that and successfully logged into A, you should INVOKE telnet > client on A to get to B, so there's no more "spawning" (from a perl module > perspective), as B and C have no clue what the heck SPAWN is.. they just > know what telnet is. Just imagine that you are invoking telnet on the > command line from host to host to host, and that's ultimately what expects > doing with the single telnet session you spawned to A. Imagine it that > way and you should be able to see enough of what's going on to know how > to use expect and code it. Remember that each time you hop, the STDOUT > and STDERR channels get lashed together, and become STDIN to the thing > that created it (parent.) They all get lashed together like the Alaskan > pipeline, all the way back to your original spawned process in your > expect script. In this daisy-chain telnet example you're trying to do, > it is the only STDIN that your script should be dealing with. > > I don't know if that's the understanding you need, or if I'm confusing you > more. Bottom line, If you can do it from the command line, i.e., telnet > from A to B to C and so forth, then so can expect. If you can't do it, > then neither can expect. It's that simple. All expect does is provide a > way to automate the steps. The only difference between opening a process > in Perl vs. Expect is that perl (by itself) cannot open a bi-directional > pipe to a process. I.e., it can do this > > open (TELNET, " telnet $HOSTA | "); > > which would allow you to read from the session, or you can do this: > > open (TELNET, "| telnet $HOSTA "); > > to write to the process, but you cannot do both at the same time like > this: > > open (TELNET, "| telnet $HOSTB | "); > > that's where Expect can help. The telnet module is an alternative that > also does this, but only for telnet. Can't spawn a chess program on the > command line and interact with it using telnet module, but you can do it > using Expect (for all you telnet.pm zealots out there, that's the > difference) > > If you want to look at primitive code that represents this idea, then it > would look something like this: > > use Expect; > > $HOSTA=xx.xx.xx.1; > $HOSTB=xx.xx.xx.2; > $HOSTC=xx.xx.xx.3; > > $username="abc"; > $password="123"; > ># ------------ ># telnet to A ># ------------ > my $exp = Expect->spawn("telnet $HOSTA") or die "Cannot spawn telnet: $! > \n"; > $timeout=20; > expect($timeout, "login: "); > $exp->send("$username\n"); > expect($timeout, "password: "); > $exp->send("$password\n"); > $expect($timeout, '-re', "[%#>] $"); # $HOSTA prompt > ># ------------ ># telnet to B ># ------------ > $exp->send("telnet $HOSTB\n"); > expect($timeout, "login: "); > $exp->send("$username\n"); > expect($timeout, "password: "); > $exp->send("$password\n"); > $expect($timeout, '-re', "[%#>] $"); # $HOSTB prompt > ># ------------ ># telnet to C ># ------------ > $exp->send("telnet $HOSTC\n"); > expect($timeout, "login: "); > $exp->send("$username\n"); > expect($timeout, "password: "); > $exp->send("$password\n"); > $expect($timeout, '-re', "[%#>] $"); # $HOSTC prompt > > > Braindead simple example, but you should get the idea. Do a perldoc on > Expect.pm and print it out, go to staples and buy a binder, put it in > there and carry it around / put it on your desk at work also. If you > REALLY want to get nuts and rule the world with Expect, go out and buy > Don Libes most excellent O'Reilly book. Tcl is such a simple language, > that you would have no problem figuring enough of it out on the fly to > literally use this book as a supercharged reference for the Perl module, > that is, unless you're a Perl zealot and can't for religious reasons.. > although the perl module is not 100% translation, it's close enough for > government work (so the saying goes.) > > > Anyways, hope this helps you man. > > > > > > > Hailey Nguyen > <Hai...@Su...> To: > Chris Muth <mut...@mc...> Sent > by: cc: Hailey Nguyen > <Hai...@Su...>, > exp...@li...urc > exp...@li... > eforge.net Subject: Re: > [Expectperl-discuss] Nested telnet > sessions using Expect.pm module > 10/02/2003 04:11 PM > > > > > > > > Hi Chris, > >>>> First you will have to login to A. That involves what you have, plus >>>> you will have to $exp->expect() for whatever telnet responds with when >>>> it asks for the password. Then use a $exp->send() to send the > password. >>>> Then $exp->expect() for the prompt on A. Once you are logged into A, >>>> use a $exp->send() to call telnet $B on A to login to B, $exp->expect() >>>> for the password prompt, and then $exp->send() it. Once logged into B, >>>> do the same to login to C, and the same for D, and the same for ... > > Still struggling with this. As soon as I logged into B from A I lose > control of that session/connection. So $exp->send() won't do anything. > Did you write something like this before. Can I have an example? > > Note: A know B but doesn't know C - in another words, to get to C you > have to go through B. > > Thanks a million, > Hailey > > >>>>> >>>>> Please show me how to do nested telnet sessions using Expect.pm > module? >>>>> >>>>> 1- telnet to machine A >>>>> 2- from A to mcahine B >>>>> 3- from B to machine C >>>>> >>>>> ----- >>>>> use Expect; >>>>> >>>>> my $exp = Expect->spawn("telnet $somehost") >>>>> or die "Cannot spawn telnet: $!\n"; >>>>> >>>>> ... >>>>> >>>>> ----- >>>>> Your help is greatly appreciated. Please reply directly to me since >>>>> I am not on the alias. >>>>> > > > > > > ------------------------------------------------------- > This sf.net email is sponsored by:ThinkGeek > Welcome to geek heaven. > http://thinkgeek.com/sf > _______________________________________________ > Expectperl-discuss mailing list > Exp...@li... > https://lists.sourceforge.net/lists/listinfo/expectperl-discuss > > > |
From: Andrew C. <an...@xt...> - 2003-10-08 04:18:23
|
Hi, What about if you want the last object to be a separate expect instance? I have a situation where I need to: telnet to a cisco router and configure an interface to provide connectivity to another device. telnet from the router to the device and login. interact. logout from the device and fallback to the cisco, deconfigure the interface and shut it down. logoff. My problem is the moron users who won't read the initial text that tells them to hit control X to exit (interact escape sequence). Most of them are logging out cleanly from the device and if this was a separate expect object, control would return to the program and I could clean up the router. The man page says the escape sequence will not work with multiple characters so I can't use "exit" etc. Can I expect from an instance while it's in interact mode? I could look for the logout command or watch for when the prompt changes back to the original router. Any ideas would be hugely appreciated. Cheers, Andrew On Sat, 2003-10-04 at 08:54, Hailey Nguyen wrote: > Hi D. Basham, > > It's definitely very helpful. Chris Muth has sent me an example and I got > my stuff to work with that. But your info is also a great help to me. > > Thanks, > HAiley Theory is what you use to describe an experience. It will never be a substitute. -- Me. Everyday. |
From: Austin S. <te...@of...> - 2003-10-08 04:32:29
|
On Wed, Oct 08, 2003 at 05:17:47PM +1300, Andrew Cutler wrote: > Hi, > > What about if you want the last object to be a separate expect instance? > I have a situation where I need to: > You could if you wanted turn/copy it into a new object, but that probably won't give you the functionality you're looking for. > telnet to a cisco router and configure an interface to provide > connectivity to another device. > > telnet from the router to the device and login. > interact. > logout from the device and fallback to the cisco, > > deconfigure the interface and shut it down. > logoff. > > My problem is the moron users who won't read the initial text that tells > them to hit control X to exit (interact escape sequence). Most of them > are logging out cleanly from the device and if this was a separate > expect object, control would return to the program and I could clean up > the router. So don't call interact. read from the user and write to the router, and vice versa. > > The man page says the escape sequence will not work with multiple > characters so I can't use "exit" etc. This is true, see above comment. Also you can still look for strings like 'connection closed by foreign host', etc. > > Can I expect from an instance while it's in interact mode? I could look > for the logout command or watch for when the prompt changes back to the > original router. > Yeah, that's what you do. You don't need to do interact to accomplish this. Also, you can use the '-i' flag to expect() to wait for input from both the device and the user. Well, that's how I would do it anyway. Austin |
From: Andrew C. <an...@xt...> - 2003-10-10 04:09:12
|
I hope this comes out O.K. My crappy mailler won't let me set the word wrap. On Wed, 2003-10-08 at 17:30, Austin Schutz wrote: > Yeah, that's what you do. You don't need to do interact to accomplish > this. Also, you can use the '-i' flag to expect() to wait for input from both > the device and the user. > Well, that's how I would do it anyway. > > > Austin Following that advice and shamelessly stealing from various examples, I've basically got that working. The guts are: ## Router interface etc configured. ## Logon to the device. $net_telnet->print("telnet $ipaddress /vrf $VRF"); ## Create a handle to STDIN my $stdin = Expect->exp_init( \*STDIN ); $stdin->stty(qw(raw -echo)); $stdin->log_stdout(0); ## Create a handle for the telnet session my $device = Expect->exp_init( \*$net_telnet ); $device->log_stdout(1); $device->log_file($expect_log); $stdin->set_group($device); ## If we see the router prompt we're not on the ## remote device anymore. Exit the expect loop. expect( undef, '-i', [$device], [qr'ROUTER#$'], '-i', [$stdin], [ qr'\n', sub { exp_continue; } ], ); ## Reset teminal or carriage returns get screwed up. $stdin->stty(qw(sane)); print "\nCleaning up config.\n"; bless $net_telnet, 'Net::Telnet'; ##Remove interface and exit. This all seems to be working great. The main problem I had was being able to see what I was typing without the input line being echoed after I pressed enter. After trying a huge combination of terminal settings I read about $exp->set_group and that fixed everything. The beauty of this setup is by adding more regexs you could parse/filter the input. For anyone who's wondering, I always use a Net::Telnet object instead of a raw IO socket on TCP 23 because I got caught out a while back by hosts expecting telnet options you can't do with raw IO. Having struggled through this I'm "interested" now, so I'd appreciate any comments or suggestions on how to do this better. Thanks for everyones help. Cheers, Andrew Anyone who isn't confused really doesn't understand the situation. -Edward R. Murrow. 1908-1965. |