IO.popen on Windows to filter stdout

Hello all,

I’ve been googling and playing with this for a while, but I’m stuck
and I figured I’d ask in case anyone’s done this before.

I’d like to use IO.popen, or something similar, to ‘filter’ the spew
coming from another programs stdout. I think I understand that I can
capture the stdout stream returned by IO.popen by using .readlines,
etc… But it still seems that the sub process is writing the output
directly to $stdout…

Of course, this is on windows, so I don’t have proper fork, etc…

Is there a way to somehow “swallow” the stdout from the sub process so
it doesn’t make it directly to the ruby process’ stdout?

Thanks in advance for any insight,
-Harold

On Thu, 22 Feb 2007, Harold H. wrote:

Of course, this is on windows, so I don’t have proper fork, etc…

Is there a way to somehow “swallow” the stdout from the sub process so it
doesn’t make it directly to the ruby process’ stdout?

Thanks in advance for any insight,
-Harold

probably the other process is writing to stderr. try

IO.popen( ‘cmd 2>&1’ ) do |pipe|
pipe.each do |line|
p line
end
end

alternatively, you may want to use systemu

http://codeforpeople.com/lib/ruby/systemu

it’s very easy to block a process using IO.popen on windows.

regards.

-a

On 2/22/07, [email protected] [email protected] wrote:

IO.popen( ‘cmd 2>&1’ ) do |pipe|
pipe.each do |line|
p line
end
end

Hi Ara, thanks for taking the time to try and help me. What you’re
saying about stderr here sounds right to me, but I tried what you have
above, and I’m still seeing the output I’m trying to ‘squash’ (read:
block) … Here is my code:
#########################
puts “ruby-link in the house!”
the_cmd = "old-Link.exe "
ARGV.each do |arg|
the_cmd << ""#{arg}" "
end

the_cmd << “2>&1”

puts “Calling: #{the_cmd}”

IO.popen( the_cmd )
#########################

And here is the output that I see: (apologies for badly wrapped lines)
ruby-link in the house!
Calling: old-Link.exe “@C:\long\path\to\some.rsp” “/NOLOGO”
“/ERRORREPORT:PROMPT” 2>&1
OLD-LINK :
<snip about 200k of nasty output from old-Link.exe>


So yeah, the output from old-Link.exe is still being filtered up to
the top and seen. What I’m looking for is a way to shut it up… :wink:

alternatively, you may want to use systemu

http://codeforpeople.com/lib/ruby/systemu

I looked at systemu and it’s not clear how it would help with this
problem. :expressionless: Apologies if I’m being dense.

it’s very easy to block a process using IO.popen on windows.

I thought so too. :wink:

Thanks again for your time,
-Harold

On 2/23/07, [email protected] [email protected] wrote:

hrrrm. this is a windozing type thing, but is it perhaps manipulating the
console directly? for instance, in unix, this can happen.

I believe that the underlying executable that I’m dealing with, namely
VC8’s “link.exe” is doing something very dastardly.

STDOUT.reopen tmp.path
STDERR.reopen tmp.path

exec cmd

When I integrate the above code, a tempfile is indeed created, but it
remains empty. And what’s more? I still see the output in the
console! (:

However, the following irb session indeed proves that stdout can be
redirected. (as well as makes me laugh out loud)

irb(main):001:0> require ‘tempfile’
=> true
irb(main):002:0> tmp = Tempfile.new Process.pid
=> #<File:C:/DOCUME~1/Harold/LOCALS~1/Temp/484.484.0>
irb(main):003:0> STDOUT.reopen tmp.path


#hrhrhr.

   @io << "#{ @prefix }: #{ line }"

stdout: 42
stderr: 42

This code is also awesome, but when I integrate it into my tool, it
has literally no effect on the outcome.

All of this is leading me to believe that VC8’s link.exe (or as I’ve
renamed it ‘old-Link.exe’) is doing something very tricky, not
involving stdout or stderr at all.

Moreover, I’ve exceeded the point where solving this problem will save
me time versus watching 200k of spewed linker warnings with each build
of my software. (of course due to a 3rd party library that wont give
me their .pdb files, and a bug in VC8 which causes /IGNORE: to be
itself ignored on the command line of the linker.)

Oh well, thanks again for the lessons, I know more about spawning
processes from Ruby on Windows than I ever thought I would.

Regards,
-Harold

From: “Harold H.” [email protected]

All of this is leading me to believe that VC8’s link.exe (or as I’ve
renamed it ‘old-Link.exe’) is doing something very tricky, not
involving stdout or stderr at all.

Sorry if you’ve already covered this (I haven’t read the whole thread.)

But, have you tried redirecting link.exe’s output from a DOS prompt
yet?

link blah > foo.out 2>&1

(Yes, surprisingly, cmd.exe supports 2>&1 syntax.)

Just wondered if even DOS is able to capture the output, or not?

Regards,

Bill

On Fri, 23 Feb 2007, Harold H. wrote:

I believe that the underlying executable that I’m dealing with, namely
VC8’s “link.exe” is doing something very dastardly.

it sure looks like it!

STDOUT.reopen tmp.path
redirected. (as well as makes me laugh out loud)

irb(main):001:0> require ‘tempfile’
=> true
irb(main):002:0> tmp = Tempfile.new Process.pid
=> #<File:C:/DOCUME~1/Harold/LOCALS~1/Temp/484.484.0>
irb(main):003:0> STDOUT.reopen tmp.path

hmm. then it looks like what’s happening might depend on the nature of
stdin,
i’d try one last thing

 require 'tempfile'

 i = Tempfile.new Process.pid
 o = Tempfile.new Process.pid
 e = Tempfile.new Process.pid
 puts i.path
 puts o.path
 puts e.path

 cmd = "put the exact command here"

 STDIN.reopen i.path
 STDOUT.reopen o.path
 STDERR.reopen e.path

 system cmd

alternatively

 require 'systemu'

 class Filter
   def initialize prefix, io
     @prefix = prefix
     @io = io
   end
   def << line
     @io << "#{ @prefix }: #{ line }"
   end
 end

 i = ''
 o = Filter.new 'stdout', STDOUT
 e = Filter.new 'stderr', STDERR

 systemu 'ruby -e"STDOUT.puts 42; STDERR.puts 42"', :stdin=>i, 

:stdout=>o, :stderr=>e

sorry i couldn’t help more.

cheers.

-a

On Fri, 23 Feb 2007, Harold H. wrote:

end
Calling: old-Link.exe “@C:\long\path\to\some.rsp” “/NOLOGO”
“/ERRORREPORT:PROMPT” 2>&1
OLD-LINK :
<snip about 200k of nasty output from old-Link.exe>

hrrrm. this is a windozing type thing, but is it perhaps manipulating
the
console directly? for instance, in unix, this can happen.

it’s hard to say without seeing your code, and the old code, but you
could try
this to prove to yourself that stdout and stderr can be diverted:

require ‘tempfile’

tmp = Tempfile.new Process.pid
puts tmp.path

cmd = “put the exact command here”

STDOUT.reopen tmp.path
STDERR.reopen tmp.path

exec cmd

this should dump everything into a tempfile. if it does, then you
should be
able to manipulate the code with popen fine.

problem. :expressionless: Apologies if I’m being dense.
harp:~ > cat a.rb
require ‘systemu’

class Filter
def initialize prefix, io
@prefix = prefix
@io = io
end
def << line
@io << “#{ @prefix }: #{ line }”
end
end

o = Filter.new ‘stdout’, STDOUT
e = Filter.new ‘stderr’, STDERR

systemu ‘ruby -e"STDOUT.puts 42; STDERR.puts 42"’, :stdout => o,
:stderr => e

harp:~ > ruby a.rb
stdout: 42
stderr: 42

-a