From: Ehsanul Hoque Date: 2009-09-11T11:27:18+09:00 Subject: Re: Can not catch PTY::ChildExited exception --_ea4a0bb7-cdbe-402a-9c19-2b928ec0f020_ Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Well=2C I'm sure I have nowhere as good an idea of PTY.spawn() as Matsumoto= does=2C but let me try to explain what your code is doing=2C and how to ge= t your desired result. First=2C you might want to consider using other methods for what you're doi= ng. You probably don't really need a pseudo terminal=2C which is what PTY g= ives you=2C and you can use more well documented methods. These two links g= ive a good overview of some of the other ways you can start subprocesses in= ruby: http://devver.net/blog/2009/06/a-dozen-or-so-ways-to-start-sub-processes-in= -ruby-part-1/ http://devver.net/blog/2009/07/a-dozen-or-so-ways-to-start-sub-processes-in= -ruby-part-2/ If you still think you really need to use a pseudo terminal=2C then read on= . PTY.spawn() doesn't block your ruby program like a call to system() would. = It simply starts the process given the command=2C and lets you continue. In= your first email=2C you mentioned that when you took out the "sleep 10" li= ne in your code=2C no exception took place at all. The reason for this is t= hat your script ended before the child did=2C since the ten seconds of slee= p were taken out. And so ruby did not have a chance to raise an exception. = Similarly=2C in your latest code example=2C "TEST END" was never printed be= cause the begin block had an exception before you even reached the 'printf "TEST END\= n"' line. The exception occurred while it was in "sleep 10". I hope that's clear=2C it messed me up too in the pa= st. To get what you want=2C you might want to use the block form for PTY.spawn(= ) instead. I just find it cleaner=2C and using the limited scope for the va= riables pipe_read etc makes sense. The variables are gone when the pseudo t= erminal is gone. What I've done is put a loop inside the PTY.spawn() block=2C which can be u= sed to handle the output from the subprocess=2C or feed it input. If you do= n't need to do that=2C you probably don't need to use PTY anyways=2C but yo= u can be the judge of that. Now=2C this loop stops when the subprocess exit= s=2C and then the rest of the ruby script continues. It seems like you also want to run some code in parallel to the subprocess= =2C but not in the loop I mentioned. For this case=2C the code below also h= as a thread. Only when the child exits does the thread stop=2C and "t.join"= finally allows the code to continue. Before "t.join" and after the thread = block though=2C you can run code in parallel to the subprocess. And then=2C= "Test End" is printed after the subprocess has exited. Here's the code: require 'pty' cmd =3D "/home3/cman/work/product/integrator/test/syb2/OCS-15_0/bin/isql -U= user2 -Puser2 -Scman2" t =3D Thread.new do begin PTY.spawn(cmd) do |pipe_read=2C pipe_write=2C pid| loop do # Code here can handle output given by your command=2C and feed it = input=2C etc # But the infinite loop will be broken by the exception caused when= the child process exits=2C and your script continues # Or you could just terminate this loop in advance=2C but remember= =2C you might reach the end of your ruby script # before the child exits=2C in case that's a problem. end end rescue PTY::ChildExited =3D> msg puts "The child has exited" rescue =3D> msg puts "A different exception:\n" + msg end end puts "Doing stuff in parallel to the subprocess here" t.join puts "Test End" I hope that was useful/clear. It was certainly too long. - Ehsan > Date: Fri=2C 11 Sep 2009 09:56:15 +0900 > From: denis.berezhnoy@gmail.com > Subject: Re: Can not catch PTY::ChildExited exception > To: ruby-talk@ruby-lang.org >=20 > Yukihiro Matsumoto wrote: > > Hi=2C > >=20 > > In message "Re: Can not catch PTY::ChildExited exception" > > on Wed=2C 9 Sep 2009 15:14:09 +0900=2C Denis Berezhnoy=20 > > writes: > >=20 > > |I have problem that I can not catch PTY::ChildExited exception. Here i= s > > |the code: > >=20 > > The exception was raised when the child process terminated > > (asynchronously)=2C so you need to wrap not only spawn but everything. > >=20 > > matz. >=20 > Hello Matsumoto-san=2C >=20 > Thank you very much for clarifications! I tried to wrap around whole=20 > code with begin rescue block and I can catch ChildExited exception. So=20 > now I have code like this: >=20 > require 'pty' >=20 > cmd =3D "/home3/cman/work/product/integrator/test/syb2/OCS-15_0/bin/isql= =20 > -Uuser2 -Puser2 -Scman2" >=20 > begin >=20 > pipe_read=2C pipe_write=2C pid =3D PTY.spawn(cmd) >=20 > sleep 10 >=20 > printf "TEST END\n" >=20 > rescue PTY::ChildExited =3D> msg > puts "Caught child exited exception!" > rescue =3D> msg > puts "Caught exception!" > rescue =3D> e > puts e.msg > puts e.type > end >=20 >=20 > But now the problem is that ChildExited exception can occur at any=20 > moment after spawn and interrupt program in random place. In my test=20 > above I never get TEST END printed. >=20 > How can I handle this in right way? >=20 > Best regards=2C > Denis > --=20 > Posted via http://www.ruby-forum.com/. >=20 _________________________________________________________________ With Windows Live=2C you can organize=2C edit=2C and share your photos. http://www.windowslive.com/Desktop/PhotoGallery= --_ea4a0bb7-cdbe-402a-9c19-2b928ec0f020_--