[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

popen in non-blocking mode

Urizev

10/6/2007 11:18:00 AM

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

--
Saludos

Juan Carlos

"¡¡Viva lo rancio!!"

12 Answers

7stud 7stud

10/6/2007 1:29:00 PM

0

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-....

Marcin Raczkowski

10/6/2007 3:11:00 PM

0

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

ThoML

10/6/2007 3:18:00 PM

0

> 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.


ara.t.howard

10/6/2007 3:22:00 PM

0


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://codeforp...
--
share your knowledge. it's a way to achieve immortality.
h.h. the 14th dalai lama



ara.t.howard

10/6/2007 3:29:00 PM

0


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://codeforp...
--
share your knowledge. it's a way to achieve immortality.
h.h. the 14th dalai lama



ara.t.howard

10/6/2007 3:41:00 PM

0


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://codeforp...
--
it is not enough to be compassionate. you must act.
h.h. the 14th dalai lama




ThoML

10/6/2007 3:48:00 PM

0

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

Thank you very much for the pointer.

Daniel DeLorme

10/7/2007 1:00:00 AM

0

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

ara.t.howard

10/7/2007 3:19:00 AM

0


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://codeforp...
--
share your knowledge. it's a way to achieve immortality.
h.h. the 14th dalai lama



Nobuyoshi Nakada

10/7/2007 6:00:00 AM

0

Hi,

At Sat, 6 Oct 2007 20:17:40 +0900,
Urizev wrote in [ruby-talk:272872]:
> 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.

Use PTY.

--
Nobu Nakada