Professional Web Applications Themes

closing stderr - Ruby

I would like to prevent some output that is going to stderr during a call to a third party lib just during that call. My first guess was: STDERR.close_write ThirdPartyLib::call_some_annoying_function STDERR.???? I guess you can see my problem. Can anyone give me a lead on this? TIA, Michael...

  1. #1

    Default closing stderr

    I would like to prevent some output that is going to stderr during a
    call to a third party lib just during that call. My first guess was:

    STDERR.close_write
    ThirdPartyLib::call_some_annoying_function
    STDERR.????

    I guess you can see my problem. Can anyone give me a lead on this?

    TIA,
    Michael


    Michael Garriss Guest

  2. #2

    Default Re: closing stderr


    "Michael Garriss" <mgarrissearthlink.net> schrieb im Newsbeitrag
    news:3F69D414.70008earthlink.net...
    > I would like to prevent some output that is going to stderr during a
    > call to a third party lib just during that call. My first guess was:
    >
    > STDERR.close_write
    > ThirdPartyLib::call_some_annoying_function
    > STDERR.????
    >
    > I guess you can see my problem. Can anyone give me a lead on this?
    >
    > TIA,
    > Michael
    >
    >
    require 'StringIO'

    oldStdErr = $stderr
    oldSTDERR = STDERR

    $stderr = StringIO.new
    STDERR = $stderr

    begin
    # lib call
    ensure
    $stderr = oldStdErr
    STDERR = oldSTDERR
    end

    robert

    Robert Klemme Guest

  3. #3

    Default Re: closing stderr

    Robert Klemme wrote:
    > "Michael Garriss" <mgarrissearthlink.net> schrieb im Newsbeitrag
    > news:3F69D414.70008earthlink.net...
    >
    >>I would like to prevent some output that is going to stderr during a
    >>call to a third party lib just during that call. My first guess was:
    >>
    >>STDERR.close_write
    >>ThirdPartyLib::call_some_annoying_function
    >>STDERR.????
    >>
    >>I guess you can see my problem. Can anyone give me a lead on this?
    >>
    >>TIA,
    >>Michael
    >>
    >>
    >
    >
    > require 'StringIO'
    >
    > oldStdErr = $stderr
    > oldSTDERR = STDERR
    >
    > $stderr = StringIO.new
    > STDERR = $stderr
    >
    > begin
    > # lib call
    > ensure
    > $stderr = oldStdErr
    > STDERR = oldSTDERR
    > end
    >
    > robert
    >
    I did it like this on windows recently:

    oldStderr = $stderr.dup
    $stderr.reopen("NUL", 'w')

    <do stuff>

    $stderr.reopen(oldStderr)

    Not sure if NUL works on linix/unix

    Alan Davies Guest

  4. #4

    Default Re: closing stderr

    On Fri, Sep 19, 2003 at 12:49:43AM +0900, Michael Garriss wrote:
    > I would like to prevent some output that is going to stderr during a
    > call to a third party lib just during that call. My first guess was:
    >
    > STDERR.close_write
    > ThirdPartyLib::call_some_annoying_function
    > STDERR.????
    If the third-party library is a Ruby library and is well-behaved,
    then you don't have to mess with STDERR; just change $stderr to
    point to someplace else.

    Remember: the global variable $stderr is where Ruby actually sends
    standard error output. The constant STDERR is just a saved
    copy of the value $stderr got when Ruby started up.

    So something like this should do the trick:

    begin
    $stderr = File.open('/dev/null', 'w')
    ThirdPartyLib::call_some_annoying_function
    ensure
    $stderr = STDERR
    end

    If, on the other hand, the third-party library is not so well-behavied
    and messes with STDERR directly, then you can close it. But you need to save
    a copy of it first and restore it later.

    begin
    errCopy = ($stderr = STDERR).dup
    STDERR.close
    ThirdPartyLib::call_some_annoying_function
    ensure
    $stderr = errCopy
    STDERR = $stderr
    end

    Note that you have to assign something open to $stderr before assigning
    to STDERR, or else the assignment to STDERR throws an exception trying to
    print the "already initialized constant" warning and the assignment
    doesn't complete. There is probably a cleaner way of doing this.

    Question on the subject of well-behaved libraries: if you invoke
    native code from Ruby, is that run with file descriptor 2 initially
    matching $stderr?

    -Mark
    Mark J. Reed Guest

  5. #5

    Default Re: closing stderr

    Scripsit illa aut ille ğRobert KlemmeĞ <bob.newsgmx.net>:
    > "Michael Garriss" <mgarrissearthlink.net> schrieb im Newsbeitrag news:3F69D414.70008earthlink.net...
    > > I would like to prevent some output that is going to stderr during a
    > > call to a third party lib just during that call. My first guess was:
    > >
    > > STDERR.close_write
    > > ThirdPartyLib::call_some_annoying_function
    > > STDERR.????
    > >
    > > I guess you can see my problem. Can anyone give me a lead on this?
    [...]
    > $stderr = StringIO.new
    > STDERR = $stderr
    Are you sure it occupies file descriptor 2 (which external libraries
    normally use)?

    def without_stderr(&block)
    save = $stderr.dup()
    $stderr.close() # this will affect STDERR, too.
    begin
    yield
    ensure
    $stderr = save.dup()
    # SIDE EFFECT: the file descriptor STDERR points to will be valid again
    end
    end

    However, this routine assumes that all file descriptors before
    $stderr are used. This is the case unless $stdin or $stdout have
    been closed. Is there something like dup2() in Ruby?


    --
    The only thing that Babelfish is good at is proving that Vogons are
    great poets.
    Josef 'Jupp' Schugt in japan.anime.evangelion
    Rudolf Polzer Guest

  6. #6

    Default Re: closing stderr

    On Thu, Sep 18, 2003 at 05:28:31PM +0100, Alan Davies wrote:
    > Not sure if NUL works on linix/unix
    Definitely not. It will just create a file in the current directory
    named "NUL". :)

    There are no magic filenames on *N?X. There are, however, special
    files which refer to hardware devices rather than disk storage. These
    can be named anything, since it's not the name that matters but
    the file attributes, but there is a standard set of such files
    in /dev on all systems. One of these is /dev/null, which points
    to the "null device", which is not a real piece of hardware but a
    virtual device that just discards everything written to it.
    Another popular virtual device is /dev/zero, which will happily output
    zero bytes as long as you care to continue reading from it.

    In any case, we came up with much the same solution, differing only
    in the filenames for the null device. The StringIO solution
    seems like a better choice for cross-platform compatibility, however.

    -Mark
    Mark J. Reed Guest

  7. #7

    Default Re: closing stderr

    Mark J. Reed wrote:
    > <snip>
    >Note that you have to assign something open to $stderr before assigning
    >to STDERR, or else the assignment to STDERR throws an exception trying to
    >print the "already initialized constant" warning and the assignment
    >doesn't complete. There is probably a cleaner way of doing this.
    >
    >
    >
    Thanks to all who responded!

    Assign something open? I don't understand. I get a syntax error on
    that assignment:

    bin/ruglyctl:132:in `require':
    /usr/www/apache/rugly/lib/rdb_rugly.rb:40: dynamic constant assignment
    (SyntaxError)
    STDERR = $stderr
    ^ from bin/ruglyctl:132:in `handle_db_cmdtype'
    from bin/ruglyctl:146

    Regards,
    Michael





    Michael Garriss Guest

  8. #8

    Default Re: closing stderr

    On Fri, Sep 19, 2003 at 02:18:35AM +0900, Michael Garriss wrote:
    > Mark J. Reed wrote:
    > >Note that you have to assign something open to $stderr before assigning
    > >to STDERR, or else the assignment to STDERR throws an exception trying to
    > >print the "already initialized constant" warning and the assignment
    > >doesn't complete. There is probably a cleaner way of doing this.
    >
    > Assign something open? I don't understand. I get a syntax error on
    > that assignment:
    What I mean is that this assignment:

    STDERR = blah

    Generates a warning:

    warning: already initialized constant STDERR

    And that warning message is sent to - where else - $stderr.
    Which means if $stderr is still pointing to a closed File object
    at the time you try to assign to STDERR, Ruby tries to send the
    warning about the assignment, fails to do so because $stderr is
    closed, and aborts the assignment.

    (It seems odd that failure to emit a warning would itself be fatal
    to the surrounding operation, but that's the behavior I'm seeing
    on final 1.8.0)
    > bin/ruglyctl:132:in `require':
    > /usr/www/apache/rugly/lib/rdb_rugly.rb:40: dynamic constant assignment
    > (SyntaxError)
    > STDERR = $stderr
    Hm, I'm not sure what that means. Is this running in mod_ruby?

    -Mark
    Mark J. Reed Guest

  9. #9

    Default Re: closing stderr

    Mark J. Reed wrote:
    >On Fri, Sep 19, 2003 at 02:18:35AM +0900, Michael Garriss wrote:
    >
    >
    >>Mark J. Reed wrote:
    >>
    >>
    >>>Note that you have to assign something open to $stderr before assigning
    >>>to STDERR, or else the assignment to STDERR throws an exception trying to
    >>>print the "already initialized constant" warning and the assignment
    >>>doesn't complete. There is probably a cleaner way of doing this.
    >>>
    >>>
    >>Assign something open? I don't understand. I get a syntax error on
    >>that assignment:
    >>
    >>
    >
    >What I mean is that this assignment:
    >
    > STDERR = blah
    >
    >Generates a warning:
    >
    > warning: already initialized constant STDERR
    >
    >And that warning message is sent to - where else - $stderr.
    >Which means if $stderr is still pointing to a closed File object
    >at the time you try to assign to STDERR, Ruby tries to send the
    >warning about the assignment, fails to do so because $stderr is
    >closed, and aborts the assignment.
    >
    >(It seems odd that failure to emit a warning would itself be fatal
    >to the surrounding operation, but that's the behavior I'm seeing
    >on final 1.8.0)
    >
    >
    >
    >>bin/ruglyctl:132:in `require':
    >>/usr/www/apache/rugly/lib/rdb_rugly.rb:40: dynamic constant assignment
    >>(SyntaxError)
    >> STDERR = $stderr
    >>
    >>
    >
    >Hm, I'm not sure what that means. Is this running in mod_ruby?
    >
    >
    No, not running this code in mod_ruby. It seems that the problem is
    that it's run from within a method. I guess I'm going to have to figure
    out a way around that.

    Michael


    Michael Garriss Guest

  10. #10

    Default Re: closing stderr

    On Fri, Sep 19, 2003 at 03:40:04AM +0900, Michael Garriss wrote:
    > >>bin/ruglyctl:132:in `require':
    > >>/usr/www/apache/rugly/lib/rdb_rugly.rb:40: dynamic constant assignment
    > >>(SyntaxError)
    > >>STDERR = $stderr
    > >>
    >
    > No, not running this code in mod_ruby. It seems that the problem is
    > that it's run from within a method.
    Oh, right. You can fix that with eval.

    eval "STDERR = $stderr"

    But this is getting uglier all the time. Are you sure the
    $stderr reassignment doesn't work for you?

    -Mark
    Mark J. Reed Guest

  11. #11

    Default Re: closing stderr


    "Rudolf Polzer" <denshimeiru-sapmctacherdurchnull.de> schrieb im
    Newsbeitrag
    news:slrnbmjng5.kqp.denshimeiru-sapmctachermessage-id.durchnull.ath.cx...
    > Scripsit illa aut ille ğRobert KlemmeĞ <bob.newsgmx.net>:
    > > "Michael Garriss" <mgarrissearthlink.net> schrieb im Newsbeitrag
    news:3F69D414.70008earthlink.net...
    > > > I would like to prevent some output that is going to stderr during a
    > > > call to a third party lib just during that call. My first guess
    was:
    > > >
    > > > STDERR.close_write
    > > > ThirdPartyLib::call_some_annoying_function
    > > > STDERR.????
    > > >
    > > > I guess you can see my problem. Can anyone give me a lead on this?
    > [...]
    > > $stderr = StringIO.new
    > > STDERR = $stderr
    >
    > Are you sure it occupies file descriptor 2 (which external libraries
    > normally use)?
    >
    > def without_stderr(&block)
    > save = $stderr.dup()
    > $stderr.close() # this will affect STDERR, too.
    > begin
    > yield
    > ensure
    > $stderr = save.dup()
    > # SIDE EFFECT: the file descriptor STDERR points to will be valid
    again
    > end
    > end
    >
    > However, this routine assumes that all file descriptors before
    > $stderr are used. This is the case unless $stdin or $stdout have
    > been closed. Is there something like dup2() in Ruby?
    This routine has a totally different problem: closing $stderr make the lib
    function abort because it will get an exception on writing to $stderr.
    $stderr has to be something that is open.

    Regards

    robert

    Robert Klemme Guest

  12. #12

    Default Re: closing stderr


    "Mark J. Reed" <markjreedmail.com> schrieb im Newsbeitrag
    news:20030918162950.GA14933mulan.thereeds.org...
    > On Fri, Sep 19, 2003 at 12:49:43AM +0900, Michael Garriss wrote:
    > > I would like to prevent some output that is going to stderr during a
    > > call to a third party lib just during that call. My first guess was:
    > >
    > > STDERR.close_write
    > > ThirdPartyLib::call_some_annoying_function
    > > STDERR.????
    >
    > If the third-party library is a Ruby library and is well-behaved,
    > then you don't have to mess with STDERR; just change $stderr to
    > point to someplace else.
    >
    > Remember: the global variable $stderr is where Ruby actually sends
    > standard error output. The constant STDERR is just a saved
    > copy of the value $stderr got when Ruby started up.
    Ah, thanks for reminding me!
    > So something like this should do the trick:
    >
    > begin
    > $stderr = File.open('/dev/null', 'w')
    > ThirdPartyLib::call_some_annoying_function
    > ensure
    > $stderr = STDERR
    > end
    I typically prefer

    $stderr = File.open('/dev/null', 'w')
    begin
    ThirdPartyLib::call_some_annoying_function
    ensure
    $stderr = STDERR
    end

    because if the resource assignment (File.open) fails with an exception, no
    assignment takes place and thus $stderr = STDERR is superfluous. In this
    simple example there is no functional and not much performance difference
    but if the init and cleanup actions are more complex then it might indeed
    be crucial to follow the pattern to do the init before the block.

    Just as an additional note, this complete scheme might break in
    multithreaded applications. You migh lose messages from other threads or
    other strange things. That's the price of $globals...
    > If, on the other hand, the third-party library is not so well-behavied
    > and messes with STDERR directly, then you can close it. But you need to
    save
    > a copy of it first and restore it later.
    >
    > begin
    > errCopy = ($stderr = STDERR).dup
    > STDERR.close
    > ThirdPartyLib::call_some_annoying_function
    > ensure
    > $stderr = errCopy
    > STDERR = $stderr
    > end
    >
    > Note that you have to assign something open to $stderr before assigning
    > to STDERR, or else the assignment to STDERR throws an exception trying
    to
    > print the "already initialized constant" warning and the assignment
    > doesn't complete. There is probably a cleaner way of doing this.
    (see above)
    > Question on the subject of well-behaved libraries: if you invoke
    > native code from Ruby, is that run with file descriptor 2 initially
    > matching $stderr?
    Dunno.

    Kind regards

    robert

    Robert Klemme Guest

  13. #13

    Default Re: closing stderr

    Scripsit illa aut ille ğRobert KlemmeĞ <bob.newsgmx.net>:
    > "Rudolf Polzer" <denshimeiru-sapmctacherdurchnull.de> schrieb im Newsbeitrag
    > news:slrnbmjng5.kqp.denshimeiru-sapmctachermessage-id.durchnull.ath.cx...
    > > Scripsit illa aut ille ğRobert KlemmeĞ <bob.newsgmx.net>:
    > > > "Michael Garriss" <mgarrissearthlink.net> schrieb im Newsbeitrag news:3F69D414.70008earthlink.net...
    > > > > I would like to prevent some output that is going to stderr during a
    > > > > call to a third party lib just during that call. My first guess was:
    > > > >
    > > > > STDERR.close_write
    > > > > ThirdPartyLib::call_some_annoying_function
    > > > > STDERR.????
    > > > >
    > > > > I guess you can see my problem. Can anyone give me a lead on this?
    > > [...]
    > > > $stderr = StringIO.new
    > > > STDERR = $stderr
    > >
    > > Are you sure it occupies file descriptor 2 (which external libraries
    > > normally use)?
    > >
    > > def without_stderr(&block)
    > > save = $stderr.dup()
    > > $stderr.close() # this will affect STDERR, too.
    > > begin
    > > yield
    > > ensure
    > > $stderr = save.dup()
    > > # SIDE EFFECT: the file descriptor STDERR points to will be valid again
    > > end
    > > end
    > >
    > > However, this routine assumes that all file descriptors before
    > > $stderr are used. This is the case unless $stdin or $stdout have
    > > been closed. Is there something like dup2() in Ruby?
    >
    > This routine has a totally different problem: closing $stderr make the lib
    > function abort because it will get an exception on writing to $stderr.
    > $stderr has to be something that is open.
    Then use the StringIO trick from the other posting.

    I thought about an external library which is an interface to an
    existing C library which writes to stderr (file descriptor 2).


    --
    The only thing that Babelfish is good at is proving that Vogons are
    great poets.
    Josef 'Jupp' Schugt in japan.anime.evangelion
    Rudolf Polzer Guest

  14. #14

    Default Re: closing stderr


    "Rudolf Polzer" <denshimeiru-sapmctacherdurchnull.de> schrieb im
    Newsbeitrag
    news:slrnbmloi3.bll.denshimeiru-sapmctachermessage-id.durchnull.ath.cx...
    > > This routine has a totally different problem: closing $stderr make the
    lib
    > > function abort because it will get an exception on writing to $stderr.
    > > $stderr has to be something that is open.
    >
    > Then use the StringIO trick from the other posting.
    >
    > I thought about an external library which is an interface to an
    > existing C library which writes to stderr (file descriptor 2).
    Even then one shouldt ensure that fd 2 is opened to something unless you
    know that the external lib simply doesn't write to stderr if that is
    closed.

    Regards

    robert

    Robert Klemme Guest

  15. #15

    Default Re: closing stderr

    Scripsit illa aut ille ğRobert KlemmeĞ <bob.newsgmx.net>:
    > "Rudolf Polzer" <denshimeiru-sapmctacherdurchnull.de> schrieb:
    > > I thought about an external library which is an interface to an
    > > existing C library which writes to stderr (file descriptor 2).
    >
    > Even then one shouldt ensure that fd 2 is opened to something unless you
    > know that the external lib simply doesn't write to stderr if that is
    > closed.
    write() to a closed FD fails, but most libs ignore the error. If
    they don't, however, it needs to be reopened to something like
    /dev/null which isn't possible in a platform-independent manner.


    --
    The only thing that Babelfish is good at is proving that Vogons are
    great poets.
    Josef 'Jupp' Schugt in japan.anime.evangelion
    Rudolf Polzer Guest

Similar Threads

  1. Help! redirecting stderr 1.6.x and 1.8 differences
    By Andrew Walrond in forum Ruby
    Replies: 2
    Last Post: May 31st, 06:46 PM
  2. reading STDERR
    By Trina Espinoza in forum PERL Beginners
    Replies: 1
    Last Post: September 12th, 01:11 AM
  3. Movie Closing?? & Windows Closing??
    By JPrice in forum Macromedia Director Lingo
    Replies: 0
    Last Post: July 29th, 01:17 AM
  4. STDERR Weirdness
    By Donnie in forum Sun Solaris
    Replies: 2
    Last Post: July 22nd, 12:56 PM
  5. [How do I:] get what's in $stderr as a string?
    By Mark Wilson in forum Ruby
    Replies: 3
    Last Post: July 6th, 05:44 PM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139