$stderr.reopen bug?

T

Tanner Burson

------=_Part_46343_10383176.1130184959074
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

Hi,
I'm working through what seems like it should be a simple operation,
re-routing STDERR to point elsewhere. I can do the following

$stderr.reopen("/dev/null")

which works fine. But what I'd like to do is capture that output, so I
figured StringIO would be the way to go. According to the docs for IO#reope=
n
it can take an IO object as it's only parameter, and use that to re-open,
but when I do the following

require 'stringio'
str_io =3D StringIO.new
$stderr.reopen(str_io)

I get

TypeError: can't convert StringIO into String

any ideas? Is the documentation just wrong, and it can only take a string
arg? Or will it take only a File IO object?

--
=3D=3D=3DTanner Burson=3D=3D=3D
(e-mail address removed)
http://tannerburson.com <---Might even work one day...

------=_Part_46343_10383176.1130184959074--
 
D

Daniel Berger

Tanner said:
Hi,
I'm working through what seems like it should be a simple operation,
re-routing STDERR to point elsewhere. I can do the following

$stderr.reopen("/dev/null")

which works fine. But what I'd like to do is capture that output, so I
figured StringIO would be the way to go. According to the docs for IO#reopen
it can take an IO object as it's only parameter, and use that to re-open,
but when I do the following

require 'stringio'
str_io = StringIO.new
$stderr.reopen(str_io)

I get

TypeError: can't convert StringIO into String

any ideas? Is the documentation just wrong, and it can only take a string
arg? Or will it take only a File IO object?

You'll need an IO object because, behind the scenes, IO.reopen grabs the fileno
from the object and uses the dup2() function (at least, on *nix).

The StringIO#fileno method exists, but returns nil, since there is no
associated fileno with a StringIO object. Actually, I don't even think it gets
that far. I suspect it's choking on the rb_io_get_io() internal function.

Whether or not this could be made to work with StringIO, I'm not sure.

Regards,

Dan
 
T

Tanner Burson

------=_Part_46655_17788981.1130186496955
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

You'll need an IO object because, behind the scenes, IO.reopen grabs the
fileno
from the object and uses the dup2() function (at least, on *nix).

The StringIO#fileno method exists, but returns nil, since there is no
associated fileno with a StringIO object. Actually, I don't even think it
gets
that far. I suspect it's choking on the rb_io_get_io() internal function.


I think its passing rb_io_get_io() clean, but returning that StringIO isn't
a "true" enough IO object, so it trys to treat the StringIO parameter as a
filename to reopen with. I was hoping there was a way around this.

Whether or not this could be made to work with StringIO, I'm not sure.


Well thanks anyway :) Good to know it wasn't something I was doing anyway.

Regards,


--
=3D=3D=3DTanner Burson=3D=3D=3D
(e-mail address removed)
http://tannerburson.com <---Might even work one day...

------=_Part_46655_17788981.1130186496955--
 
E

Eric Hodel

Hi,
I'm working through what seems like it should be a simple operation,
re-routing STDERR to point elsewhere. I can do the following

$stderr.reopen("/dev/null")

which works fine. But what I'd like to do is capture that output, so I
figured StringIO would be the way to go. According to the docs for
IO#reopen
it can take an IO object as it's only parameter, and use that to re-
open,
but when I do the following

require 'stringio'
str_io = StringIO.new
$stderr.reopen(str_io)

I get

TypeError: can't convert StringIO into String

any ideas?

$stderr = str_io

$stderr.puts 'hi'
warn 'warning'

$stderr.rewind
puts $stderr.read
 
T

Tanner Burson

------=_Part_47207_27739920.1130189041190
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

$stderr =3D str_io

$stderr.puts 'hi'
warn 'warning'

$stderr.rewind
puts $stderr.read


I tried this approach first, and it didn't seem to accomplish anything (IRB
dump below)

irb(main):007:0> require 'stringio'
=3D> false
irb(main):008:0> str_io =3D StringIO.new("")
=3D> #<StringIO:0x402f8df8>
irb(main):009:0> $stderr =3D str_io
=3D> #<StringIO:0x402f8df8>
irb(main):010:0> `asdf` #bad command, dumps to stderr
(irb):10: command not found: asdf
=3D> ""
irb(main):011:0> $stderr.rewind
=3D> 0
irb(main):012:0> puts $stderr.read

=3D> nil
irb(main):013:0>

as compared to the version reopening as file:

irb(main):001:0> require 'stringio'
=3D> true
irb(main):002:0> $stderr.reopen('/dev/null','w+')
=3D> #<IO:/dev/null>
irb(main):003:0> `asdf` #bad command again
=3D> ""

any idea why there is such a difference between the two?

--
Eric Hodel - (e-mail address removed) - http://segment7.net
FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04


--
=3D=3D=3DTanner Burson=3D=3D=3D
(e-mail address removed)
http://tannerburson.com <---Might even work one day...

------=_Part_47207_27739920.1130189041190--
 
J

Jean-Claude Arbaut

Tanner Burson wrote:

I tried this approach first, and it didn't seem to accomplish anything (IRB
dump below)

irb(main):007:0> require 'stringio'
=> false
irb(main):008:0> str_io = StringIO.new("")
=> #<StringIO:0x402f8df8>
irb(main):009:0> $stderr = str_io
=> #<StringIO:0x402f8df8>
irb(main):010:0> `asdf` #bad command, dumps to stderr
(irb):10: command not found: asdf
=> ""
irb(main):011:0> $stderr.rewind
=> 0
irb(main):012:0> puts $stderr.read

=> nil
irb(main):013:0>

as compared to the version reopening as file:

irb(main):001:0> require 'stringio'
=> true
irb(main):002:0> $stderr.reopen('/dev/null','w+')
=> #<IO:/dev/null>
irb(main):003:0> `asdf` #bad command again
=> ""

any idea why there is such a difference between the two?

I have not a complete answer (I'd need to look a irb source), but an hint:

irb(main):001:0> warn 'bouh'
bouh
=> nil
irb(main):002:0> `bouh`
(irb):2: command not found: bouh
=> ""

The two messages are not formated the same way, so I suspect
they are not sent to the same "stderr".
Actually, the line "command not found: bouh" is the answer
from the shell, and the warning is processed inside Ruby.
Maybe $stderr assignment is only valid for ruby output.
If I'm not wrong:
* if you reopen $stderr, you manipulate the original *file*
in /dev/stderr, therefore the shell will send its error
to the same file as Ruby
* but if you assign $stderr, the file /dev/stderr doesn't
change, only the "file" Ruby errors are sent to does.
I'm not completely sure it works that way, though...
 
N

nobu.nokada

Hi,

At Tue, 25 Oct 2005 06:24:04 +0900,
Tanner Burson wrote in [ruby-talk:162357]:
I tried this approach first, and it didn't seem to accomplish anything (IRB
dump below)

First of all, StringIO is a process internal object, so it
can't be passed to other processes.

unless f = IO.popen("-")
STDERR.reopen(STDOUT)
exec "nosuchcommand"
end
p f.read #=> "-e:1:in `exec': No such file or directory - nosuchcommand (Errno::ENOENT)\n\tfrom -e:1\n"
 
T

Tanner Burson

Hi,

At Tue, 25 Oct 2005 06:24:04 +0900,
Tanner Burson wrote in [ruby-talk:162357]:
I tried this approach first, and it didn't seem to accomplish anything = (IRB
dump below)

First of all, StringIO is a process internal object, so it
can't be passed to other processes.
Makes perfect sense. I wasn't aware that I was re-assigning the
STDERR for all processes and not just the current Ruby process.=20
Thanks.
unless f =3D IO.popen("-")
STDERR.reopen(STDOUT)
exec "nosuchcommand"
end
p f.read #=3D> "-e:1:in `exec': No such file or directory - nosuchcommand=
(Errno::ENOENT)\n\tfrom -e:1\n"
 
E

Eric Hodel

I tried this approach first, and it didn't seem to accomplish
anything (IRB
dump below)

irb(main):007:0> require 'stringio'
=> false
irb(main):008:0> str_io = StringIO.new("")
=> #<StringIO:0x402f8df8>
irb(main):009:0> $stderr = str_io
=> #<StringIO:0x402f8df8>
irb(main):010:0> `asdf` #bad command, dumps to stderr
(irb):10: command not found: asdf
=> ""
irb(main):011:0> $stderr.rewind
=> 0
irb(main):012:0> puts $stderr.read

=> nil
irb(main):013:0>

as compared to the version reopening as file:

irb(main):001:0> require 'stringio'
=> true
irb(main):002:0> $stderr.reopen('/dev/null','w+')
=> #<IO:/dev/null>
irb(main):003:0> `asdf` #bad command again
=> ""

any idea why there is such a difference between the two?

You really want open3:

require 'open3'

stdin, stdout, stderr = Open3.popen3('your command')
 

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

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,521
Members
44,995
Latest member
PinupduzSap

Latest Threads

Top