popen in non-blocking mode

U

Urizev

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!!"
 
7

7stud --

Urizev said:
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.
 
M

Marcin Raczkowski

Urizev said:
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
 
T

tho_mica_l

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

ara.t.howard

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/
 
A

ara.t.howard

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/
 
A

ara.t.howard

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/
 
D

Daniel DeLorme

ara.t.howard said:
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
 
A

ara.t.howard

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/
 
N

Nobuyoshi Nakada

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

Urizev

2007/10/7 said:
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.

What is PTY?

--=20
Saludos

Juan Carlos

"=A1=A1Viva lo rancio!!"
 
A

ara.t.howard

2007/10/7 said:
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.

What is PTY?


http://en.wikipedia.org/wiki/Pseudo_terminal

ruby included a library for manipulating them.


a @ http://codeforpeople.com/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,147
Messages
2,570,833
Members
47,380
Latest member
AlinaBlevi

Latest Threads

Top