Intercepting STDERR

Discussion in 'Ruby' started by Phrogz, Mar 1, 2006.

  1. Phrogz

    Phrogz Guest

    I'm writing a Ruby script to run Lua code for TextMate. Using:
    output = `lua #{filename}`
    works when the file prints happily, but when an error occurs (e.g. a
    syntax error in the file) the error message is printed to stderr (I
    think) and 'escapes' my capture.

    How/can I catch output to stderr from another system command? (I want
    to use the output later, I just don't want it spat out at that point.)
     
    Phrogz, Mar 1, 2006
    #1
    1. Advertising

  2. On Mar 1, 2006, at 6:43 PM, Phrogz wrote:

    > How/can I catch output to stderr from another system command? (I want
    > to use the output later, I just don't want it spat out at that point.)


    You could do:

    output = `command 2>&1`

    However, now $stderr is mixed in with $stdout.

    -- Daniel
     
    Daniel Harple, Mar 1, 2006
    #2
    1. Advertising

  3. Phrogz

    Phrogz Guest

    That'll do for now, thanks! :)
     
    Phrogz, Mar 1, 2006
    #3
  4. Phrogz

    Guest

    On Thu, 2 Mar 2006, Phrogz wrote:

    > I'm writing a Ruby script to run Lua code for TextMate. Using:
    > output = `lua #{filename}`
    > works when the file prints happily, but when an error occurs (e.g. a
    > syntax error in the file) the error message is printed to stderr (I
    > think) and 'escapes' my capture.
    >
    > How/can I catch output to stderr from another system command? (I want
    > to use the output later, I just don't want it spat out at that point.)
    >
    >


    harp:~ > gem install session >/dev/null 2>&1 && echo 'success'
    success


    harp:~ > cat a.rb
    require 'rubygems'
    require 'session'
    sh = Session::new
    command = %Q( ruby -e" STDERR.puts :stderr; STDOUT.puts :stdout " )
    stdout, stderr = sh.execute command

    require 'yaml'
    y "stdout" => stdout
    y "stderr" => stderr
    y "sh.status" => sh.status


    harp:~ > ruby a.rb
    ---
    stdout: |
    stdout

    ---
    stderr: |
    stderr

    ---
    sh.status: 0


    -a

    --
    judge your success by what you had to give up in order to get it.
    - h.h. the 14th dali lama
     
    , Mar 1, 2006
    #4
  5. On Mar 1, 2006, at 1:58 PM, Phrogz wrote:

    > That'll do for now, thanks! :)
    >
    >


    You may want to check out IO.popen and IO.popen3 (or is it popen2? I
    can never remembr the numbers)
     
    Logan Capaldo, Mar 1, 2006
    #5
  6. Phrogz

    Phrogz Guest

    That's awesome, ara. Unfortunately, I need to write something that will
    work on random MacOS machines witj a default Ruby install. Can I poke
    about in the innards of session and steal ideas/code?
     
    Phrogz, Mar 2, 2006
    #6
  7. Phrogz

    Guest

    On Thu, 2 Mar 2006, Phrogz wrote:

    > That's awesome, ara. Unfortunately, I need to write something that will
    > work on random MacOS machines witj a default Ruby install. Can I poke
    > about in the innards of session and steal ideas/code?


    absolutely. basically what you're after is open3 - it's in the stdlib and
    will probably suffice. session is overkill if you're not running multiple
    commands per session (no pun intended) anyhow.

    anyhow, here's the essence:

    harp:~ > cat a.rb
    def spawn command, opts = {}
    require 'open3'
    stdin = opts.values_at:)stdin, 'stdin', 0).compact.first
    stdout = opts.values_at:)stdout, 'stdout', 1).compact.first
    stderr = opts.values_at:)stderr, 'stderr', 2).compact.first

    Open3::popen3(command) do |i,o,e|
    i << stdin if stdin
    i.close # important!
    o.each{|line| stdout << line} if stdout
    e.each{|line| stderr << wrine} if stderr
    end

    $?.exitstatus
    end

    stdout, stderr = '', ''
    exitstatus = spawn 'cat', 0=>42, 1=>stdout, 2=>stderr

    require 'yaml'
    y 'exitstatus' => exitstatus,
    'stdout' => stdout,
    'stderr' => stderr


    harp:~ > ruby a.rb
    ---
    stdout: "42"
    stderr: ""
    exitstatus: 0


    regards.

    -a

    --
    judge your success by what you had to give up in order to get it.
    - h.h. the 14th dali lama
     
    , Mar 2, 2006
    #7
  8. Phrogz

    Phrogz Guest

    Thanks so much, Ara. That's almost perfect, except that the exitstatus
    seems to be eaten. No matter what happens, I get a clean 0 exitstatus.
    For example:

    require 'open3'

    `lua xxx`
    #=> lua: cannot open xxx: No such file or directory

    p $?.exitstatus
    #=> 1

    output, errors = '', ''
    p Open3::popen3( "lua xxx" ){ |i,o,e|
    i.close
    o.each { |line| output << line }
    e.each { |line| errors << line }
    $?.exitstatus
    }
    #=> 0


    I can mostly infer the failure based on whether or not messages came to
    stderr, but it'd be nice to know for sure.
     
    Phrogz, Mar 4, 2006
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Timothy Parez
    Replies:
    0
    Views:
    401
    Timothy Parez
    Mar 6, 2004
  2. Al
    Replies:
    1
    Views:
    409
    RickB
    Jul 1, 2003
  3. Nick
    Replies:
    2
    Views:
    364
  4. Stu
    Replies:
    1
    Views:
    373
    William F. Robertson, Jr.
    Feb 22, 2005
  5. Guest
    Replies:
    4
    Views:
    575
    Brock Allen
    Aug 3, 2005
Loading...

Share This Page