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?
···
--
===Tanner Burson===
tanner.burson@gmail.com
http://tannerburson.com <---Might even work one day...
Tanner Burson wrote:
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
$stderr = str_io
$stderr.puts 'hi'
warn 'warning'
$stderr.rewind
puts $stderr.read
···
On Oct 24, 2005, at 1:16 PM, Tanner Burson wrote:
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?
--
Eric Hodel - drbrain@segment7.net - http://segment7.net
FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04
Tanner Burson wrote:
> 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.
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,
···
On 10/24/05, Daniel Berger <Daniel.Berger@qwest.com> wrote:
Dan
--
===Tanner Burson===
tanner.burson@gmail.com
http://tannerburson.com <---Might even work one day...
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?
···
On 10/24/05, Eric Hodel <drbrain@segment7.net> wrote:
On Oct 24, 2005, at 1:16 PM, Tanner Burson wrote:
> 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
--
Eric Hodel - drbrain@segment7.net - http://segment7.net
FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04
--
===Tanner Burson===
tanner.burson@gmail.com
http://tannerburson.com <---Might even work one day...
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...
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"
···
--
Nobu Nakada
You really want open3:
require 'open3'
stdin, stdout, stderr = Open3.popen3('your command')
···
On Oct 24, 2005, at 2:24 PM, Tanner Burson wrote:
On 10/24/05, Eric Hodel <drbrain@segment7.net> wrote:
$stderr = 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'
=> 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?
--
Eric Hodel - drbrain@segment7.net - http://segment7.net
FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04
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.
Thanks.
···
On 10/24/05, nobu.nokada@softhome.net <nobu.nokada@softhome.net> wrote:
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"
--
Nobu Nakada
--
===Tanner Burson===
tanner.burson@gmail.com
http://tannerburson.com <---Might even work one day...