Running external process?

Hi all,

Is there a simple way to spawn an external program, feed its stdin, and
get its stdout?

The problem with popen is, if I want to feed a few MB’s of input to it,
then it hangs (I suspect that its stdout IO buffer is full) before I
could read out its stdout on the next line. So, the following do not
work:

io=IO.popen(“externalfilter”)
io.write(verybigstring)
result=io.read

Thanks,
Ferenc

require ‘open3’
Open3.popen3(“externalfilter”) { |sin,sout,serr|
sin.write(verybigstring)
result = sout.read
}

···

On Sunday 18 January 2004 5:39 am, Ferenc Engard wrote:

Hi all,

Is there a simple way to spawn an external program, feed its stdin,
and get its stdout?

The problem with popen is, if I want to feed a few MB’s of input to
it, then it hangs (I suspect that its stdout IO buffer is full)
before I could read out its stdout on the next line. So, the
following do not work:

io=IO.popen(“externalfilter”)
io.write(verybigstring)
result=io.read


Wesley J. Landaker - wjl@icecavern.net
OpenPGP FP: 4135 2A3B 4726 ACC5 9094 0097 F0A9 8A4C 4CD6 E3D2

“Ferenc Engard” ferenc@engard.hu schrieb im Newsbeitrag
news:400A7E96.F52F09C6@engard.hu…

Hi all,

Is there a simple way to spawn an external program, feed its stdin, and
get its stdout?

The problem with popen is, if I want to feed a few MB’s of input to it,
then it hangs (I suspect that its stdout IO buffer is full) before I
could read out its stdout on the next line. So, the following do not
work:

io=IO.popen(“externalfilter”)
io.write(verybigstring)
result=io.read

You need at least two threads or non blocking IO. How about:

IO.popen( “cat”, “w+” ) do |io|
r = Thread.new(io) do |reader|
while ( line = reader.gets )
line.chomp!
$stdout.puts line
end
end

(1…100000).each {|i| io.puts i}
r.join
end

Regards

robert

Date: Sun, 18 Jan 2004 21:39:41 +0900
From: Ferenc Engard ferenc@engard.hu
Newsgroups: comp.lang.ruby
Subject: running external process?

Hi all,

Is there a simple way to spawn an external program, feed its stdin, and
get its stdout?

The problem with popen is, if I want to feed a few MB’s of input to it,
then it hangs (I suspect that its stdout IO buffer is full) before I
could read out its stdout on the next line. So, the following do not
work:

io=IO.popen(“externalfilter”)
io.write(verybigstring)
io.close # the program is still reading it’s stding here
result=io.read

Thanks,
Ferenc

-a

···

On Sun, 18 Jan 2004, Ferenc Engard wrote:

ATTN: please update your address books with address below!

===============================================================================

EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
PHONE :: 303.497.6469
ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
STP :: Solar-Terrestrial Physics Data | NCEI
NGDC :: http://www.ngdc.noaa.gov/
NESDIS :: http://www.nesdis.noaa.gov/
NOAA :: http://www.noaa.gov/
US DOC :: http://www.commerce.gov/

The difference between art and science is that science is what we
understand well enough to explain to a computer.
Art is everything else.
– Donald Knuth, “Discover”

/bin/sh -c ‘for l in ruby perl;do $l -e “print "\x3a\x2d\x29\x0a"”;done’
===============================================================================

Or (should have mentioned this in my first e-mail) if that still hangs,
you might try using Threads:

require ‘open3’
Open3.popen3(“externalfilter”) { |sin,sout,serr|
threads =
threads << Thread.new {
sin.write(verybigstring)
}
threads << Thread.new {
result = sout.read
}
threads.each {|t| t.join }
}

···

On Sunday 18 January 2004 8:26 am, Wesley J Landaker wrote:

On Sunday 18 January 2004 5:39 am, Ferenc Engard wrote:

Hi all,

Is there a simple way to spawn an external program, feed its stdin,
and get its stdout?

The problem with popen is, if I want to feed a few MB’s of input to
it, then it hangs (I suspect that its stdout IO buffer is full)
before I could read out its stdout on the next line. So, the
following do not work:

io=IO.popen(“externalfilter”)
io.write(verybigstring)
result=io.read

require ‘open3’
Open3.popen3(“externalfilter”) { |sin,sout,serr|
sin.write(verybigstring)
result = sout.read
}


Wesley J. Landaker - wjl@icecavern.net
OpenPGP FP: 4135 2A3B 4726 ACC5 9094 0097 F0A9 8A4C 4CD6 E3D2

The problem with popen is, if I want to feed a few MB’s of input to it,
then it hangs (I suspect that its stdout IO buffer is full) before I
could read out its stdout on the next line. So, the following do not
work:

io=IO.popen(“externalfilter”)
io.write(verybigstring)
result=io.read

You need at least two threads or non blocking IO. How about:

IO.popen( “cat”, “w+” ) do |io|
r = Thread.new(io) do |reader|
while ( line = reader.gets )
line.chomp!
$stdout.puts line
end
end

(1…100000).each {|i| io.puts i}
r.join
end

Thank you, this is what I need. Since I program in ruby, a 8-9 rows of
code seems too difficult to write by myself. :-/

Ferenc