How to separate stdout & stderr from executed shell command

I would like to create a method which executes a given shell command
and returns an array containing three things: 1) stdout of the command
as a string, 2) stderr of the command as a string, and 3) the exit
status. I'm having trouble figuring out how to get stdout and stderr
as separate output.

Here's an illustration of the desired result I'm after:

  > my_exec_command("ls existant_file")
  => ["existant_file\n", "", 0]

  > my_exec_command("ls NON_existant_file")
  => ["", "ls: NON_existant_file: No such file or directory\n", 2]

Any pointers on how to implement my_exec_command?

PS: Unless there's a simpler way, if someone could just point me to an
API that provides stdout and stderr of sub-processes as IO objects, I
could probably figure it out from there. Thanks!

···

On Mar 14, 11:40 am, jqwo...@gmail.com wrote:

I would like to create a method which executes a given shell command
and returns an array containing three things: 1) stdout of the command
as a string, 2) stderr of the command as a string, and 3) the exit
status. I'm having trouble figuring out how to get stdout and stderr
as separate output.

Here's an illustration of the desired result I'm after:

  > my_exec_command("ls existant_file")
  => ["existant_file\n", "", 0]

  > my_exec_command("ls NON_existant_file")
  => ["", "ls: NON_existant_file: No such file or directory\n", 2]

Any pointers on how to implement my_exec_command?

unknown wrote:

···

On Mar 14, 11:40 am, jqwo...@gmail.com wrote:

  > my_exec_command("ls NON_existant_file")
  => ["", "ls: NON_existant_file: No such file or directory\n", 2]

Any pointers on how to implement my_exec_command?

PS: Unless there's a simpler way, if someone could just point me to an
API that provides stdout and stderr of sub-processes as IO objects, I
could probably figure it out from there. Thanks!

Take a look at the IO class.
The Pickaxe book has some good examples.

-r.
--
Posted via http://www.ruby-forum.com/\.

Hi,

require "open3"

stdin, stdout, stderr = Open3.popen3('nroff -man')

Try it!

Arlen

The closest API I could find is IO::popen. But as the doc for
IO::popen says "...the subprocess's standard input and output will be
connected..." So far I haven't found any way to get stdout and stderr
of a sub-process *separately*.

Any other pointers?

···

On Mar 14, 12:16 pm, Rodrigo Bermejo <rodrigo.berm...@ps.ge.com> wrote:

unknown wrote:
> On Mar 14, 11:40 am, jqwo...@gmail.com wrote:

>> > my_exec_command("ls NON_existant_file")
>> => ["", "ls: NON_existant_file: No such file or directory\n", 2]

>> Any pointers on how to implement my_exec_command?

> PS: Unless there's a simpler way, if someone could just point me to an
> API that provides stdout and stderr of sub-processes as IO objects, I
> could probably figure it out from there. Thanks!

Take a look at the IO class.
The Pickaxe book has some good examples.

-r.
--
Posted viahttp://www.ruby-forum.com/.

Yes, Ruby comes with a standard library for this, called open3. Here are the docs for the method you want:

$ qri Open3#popen3
----------------------------------------------------------- Open3#popen3
      popen3(*cmd) {|| ...}

···

On Mar 14, 2008, at 2:49 PM, jqwoods@gmail.com wrote:

On Mar 14, 12:16 pm, Rodrigo Bermejo <rodrigo.berm...@ps.ge.com> > wrote:

unknown wrote:

On Mar 14, 11:40 am, jqwo...@gmail.com wrote:

> my_exec_command("ls NON_existant_file")
=> ["", "ls: NON_existant_file: No such file or directory\n", 2]

Any pointers on how to implement my_exec_command?

PS: Unless there's a simpler way, if someone could just point me to an
API that provides stdout and stderr of sub-processes as IO objects, I
could probably figure it out from there. Thanks!

Take a look at the IO class.
The Pickaxe book has some good examples.

-r.
--
Posted viahttp://www.ruby-forum.com/.

The closest API I could find is IO::popen. But as the doc for
IO::popen says "...the subprocess's standard input and output will be
connected..." So far I haven't found any way to get stdout and stderr
of a sub-process *separately*.

Any other pointers?

------------------------------------------------------------------------
      Open stdin, stdout, and stderr streams and start external
      executable. Non-block form:

        require 'open3'

        [stdin, stdout, stderr] = Open3.popen3(cmd)

      Block form:

        require 'open3'

        Open3.popen3(cmd) { |stdin, stdout, stderr| ... }

      The parameter cmd is passed directly to Kernel#exec.

Hope that helps.

James Edward Gray II

Exactly what I was looking for. Thanks!

···

On Mar 14, 12:58 pm, James Gray <ja...@grayproductions.net> wrote:

On Mar 14, 2008, at 2:49 PM, jqwo...@gmail.com wrote:

> On Mar 14, 12:16 pm, Rodrigo Bermejo <rodrigo.berm...@ps.ge.com> > > wrote:
>> unknown wrote:
>>> On Mar 14, 11:40 am, jqwo...@gmail.com wrote:

>>>> > my_exec_command("ls NON_existant_file")
>>>> => ["", "ls: NON_existant_file: No such file or directory\n", 2]

>>>> Any pointers on how to implement my_exec_command?

>>> PS: Unless there's a simpler way, if someone could just point me
>>> to an
>>> API that provides stdout and stderr of sub-processes as IO
>>> objects, I
>>> could probably figure it out from there. Thanks!

>> Take a look at the IO class.
>> The Pickaxe book has some good examples.

>> -r.
>> --
>> Posted viahttp://www.ruby-forum.com/.

> The closest API I could find is IO::popen. But as the doc for
> IO::popen says "...the subprocess's standard input and output will be
> connected..." So far I haven't found any way to get stdout and stderr
> of a sub-process *separately*.

> Any other pointers?

Yes, Ruby comes with a standard library for this, called open3. Here
are the docs for the method you want:

$ qri Open3#popen3
----------------------------------------------------------- Open3#popen3
      popen3(*cmd) {|| ...}
------------------------------------------------------------------------
      Open stdin, stdout, and stderr streams and start external
      executable. Non-block form:

        require 'open3'

        [stdin, stdout, stderr] = Open3.popen3(cmd)

      Block form:

        require 'open3'

        Open3.popen3(cmd) { |stdin, stdout, stderr| ... }

      The parameter cmd is passed directly to Kernel#exec.

Hope that helps.

James Edward Gray II