Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > popen in non-blocking mode

Reply
Thread Tools

popen in non-blocking mode

 
 
Urizev
Guest
Posts: n/a
 
      10-06-2007
I want to execute a program which prompts for commads from standard
input and returns responses to standard output, this process repeats
several times. I want to execute it from a ruby application. I tried
to use a popen call to do it, but it do not flush the output until
input channel is closed. I need to know what the process request
before sending a response.

Regards

--=20
Saludos

Juan Carlos

"=A1=A1Viva lo rancio!!"

 
Reply With Quote
 
 
 
 
7stud --
Guest
Posts: n/a
 
      10-06-2007
Urizev wrote:
> I want to execute a program which prompts for commads from standard
> input and returns responses to standard output, this process repeats
> several times. I want to execute it from a ruby application. I tried
> to use a popen call to do it, but it do not flush the output until
> input channel is closed. I need to know what the process request
> before sending a response.
>


It's hard to tell what you mean by 'output' and 'input'. There are two
sides to a pipe so side1's output is side2's input and side2's output is
side1's input. So, when you say *it* doesn't flush the output, what do
you mean? What is *it*?

Also, what are you referring to when you say 'process'? When you call
popen, you are starting what is typically called a "subprocess". In
any case, there are two processes, so which one are you referring to?

If something is buffering output, then program it so that it doesn't
buffer output, i.e. call flush. If you are unable to reprogram some
code somewhere to call flush, then I think the only way you can make it
flush is by causing one side to terminate, which automatically flushes
the pipe.
--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
 
 
 
Marcin Raczkowski
Guest
Posts: n/a
 
      10-06-2007
Urizev wrote:
> I want to execute a program which prompts for commads from standard
> input and returns responses to standard output, this process repeats
> several times. I want to execute it from a ruby application. I tried
> to use a popen call to do it, but it do not flush the output until
> input channel is closed. I need to know what the process request
> before sending a response.
>
> Regards
>


this question was repeated over and over a least 20 times (quick google
search spawned 10 threads) and answer ultimatelly as the same - someone
already did it - use open4 gem / visit codeforpeople.com website

 
Reply With Quote
 
tho_mica_l
Guest
Posts: n/a
 
      10-06-2007
> If something is buffering output, then program it so that it doesn't
> buffer output, i.e. call flush.


Based on my own experiences, I think the OP is in a situation where
he
is looking for some kind of peekchar functionality (with some
timeout)
to check if there is some output to consume. He would have to give us
a
code example but I suspect he tries to do something like:

inout = IO.popen('ruby', File::RDWR)
inout.read

Which is tricky to handle but feasible when consuming the output
charwise and if one can tell the interpreter is ready for input and
won't output any new characters.

Anyway, the better solution would be to use open3, I think. There is
a
windows-implementation somewhere I think but I never tried it.


 
Reply With Quote
 
ara.t.howard
Guest
Posts: n/a
 
      10-06-2007

On Oct 6, 2007, at 5:17 AM, Urizev wrote:

> I want to execute a program which prompts for commads from standard
> input and returns responses to standard output, this process repeats
> several times. I want to execute it from a ruby application. I tried
> to use a popen call to do it, but it do not flush the output until
> input channel is closed. I need to know what the process request
> before sending a response.


the general concepts are:


IO.popen cmd, 'r+' do |pipe|

pipe.sync = true ### you can do this once

loop do
buf = pipe.gets

case buf
when /A/
pipe.puts 'response_A'
when /B/
pipe.puts 'response_B'
end

pipe.flush ### or this after each write
end

end


kind regards.

a @ http://codeforpeople.com/
--
share your knowledge. it's a way to achieve immortality.
h.h. the 14th dalai lama



 
Reply With Quote
 
ara.t.howard
Guest
Posts: n/a
 
      10-06-2007

On Oct 6, 2007, at 9:20 AM, tho_mica_l wrote:

> Anyway, the better solution would be to use open3, I think. There is
> a
> windows-implementation somewhere I think but I never tried it.



search the archives - it has a fatally flawed impl.

regards.

ps. on windows you may want to check out systemu, also on
codeforpeople.

regards.

a @ http://codeforpeople.com/
--
share your knowledge. it's a way to achieve immortality.
h.h. the 14th dalai lama



 
Reply With Quote
 
ara.t.howard
Guest
Posts: n/a
 
      10-06-2007

On Oct 6, 2007, at 9:10 AM, Marcin Raczkowski wrote:

> this question was repeated over and over a least 20 times (quick
> google search spawned 10 threads) and answer ultimatelly as the
> same - someone already did it - use open4 gem / visit
> codeforpeople.com website


heh - i wrote that i and i didn't suggest that. good one though!

actually that will only help on *nix. dunno if that helps the OP or
not? otherwise check out both open4 *and* session - both on http://
codeforpeople.com/

session.rb shows how to communicate with a subprocess as you are -
check out the Bash and IDL clients.

cheers.

a @ http://codeforpeople.com/
--
it is not enough to be compassionate. you must act.
h.h. the 14th dalai lama




 
Reply With Quote
 
tho_mica_l
Guest
Posts: n/a
 
      10-06-2007
> ps. on windows you may want to check out systemu, also on
> codeforpeople.


Thank you very much for the pointer.

 
Reply With Quote
 
Daniel DeLorme
Guest
Posts: n/a
 
      10-07-2007
ara.t.howard wrote:
> the general concepts are:
>
> IO.popen cmd, 'r+' do |pipe|
> pipe.sync = true ### you can do this once


Except that doesn't work. If the subprocess doesn't flush its output,
setting sync to true won't change anything. I tested with this:

IO.popen("ruby -e '10.times{puts rand;sleep 1}'") do |pipe|
pipe.sync = true
while str = pipe.gets
puts str
end
end

and I get the output in one big block after 10 seconds. Does open3/open4
change that? Somehow I doubt it.

Daniel

 
Reply With Quote
 
ara.t.howard
Guest
Posts: n/a
 
      10-07-2007

On Oct 6, 2007, at 7:00 PM, Daniel DeLorme wrote:

>
> Except that doesn't work. If the subprocess doesn't flush its
> output, setting sync to true won't change anything. I tested with
> this:
>
> IO.popen("ruby -e '10.times{puts rand;sleep 1}'") do |pipe|
> pipe.sync = true
> while str = pipe.gets
> puts str
> end
> end
>
> and I get the output in one big block after 10 seconds. Does open3/
> open4 change that? Somehow I doubt it.


not directly, although setting the STDOUT.sync=true *before* running
popen will have that affect on some systems - where that's inherited
parent -> child.

you are correct that you can't completly control the buffering
behaviour of child processes, however.


cheers.

a @ http://codeforpeople.com/
--
share your knowledge. it's a way to achieve immortality.
h.h. the 14th dalai lama



 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
re: mmm-mode, python-mode and doctest-mode? John J Lee Python 0 08-07-2007 07:49 PM
re: mmm-mode, python-mode and doctest-mode? Edward Loper Python 0 08-07-2007 08:58 AM
File.popen/IO.popen hariwise@gmail.com Ruby 1 05-20-2006 08:20 AM
mmm-mode, python-mode and doctest-mode? John J Lee Python 3 12-01-2005 08:35 PM
Safe Mode (?) - It is meant to be normal mode but looks like safe mode English Patient Computer Support 3 10-03-2004 11:10 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57