# How to separate stdout & stderr from executed shell command

**URL:** <https://www.ruby-forum.com/t/how-to-separate-stdout-stderr-from-executed-shell-command/131964>\
**Category:** Ruby\
**Created:** [March 14, 2008, 7:47pm UTC](https://www.ruby-forum.com/t/how-to-separate-stdout-stderr-from-executed-shell-command/131964 "2008-03-14T19:47:45Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [March 14, 2008, 7:47pm UTC](https://www.ruby-forum.com/t/how-to-separate-stdout-stderr-from-executed-shell-command/131964/1 "2008-03-14T19:47:45Z")

</div>

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:

irb\> my\_exec\_command(“ls existant\_file”)  
=\> [“existant\_file\n”, “”, 0]

irb\> 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?

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [March 14, 2008, 7:48pm UTC](https://www.ruby-forum.com/t/how-to-separate-stdout-stderr-from-executed-shell-command/131964/2 "2008-03-14T19:48:20Z")

</div>

On Mar 14, 11:40 am, removed\_email\_address@domain.invalid wrote:

> irb\> 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!

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [March 14, 2008, 8:16pm UTC](https://www.ruby-forum.com/t/how-to-separate-stdout-stderr-from-executed-shell-command/131964/3 "2008-03-14T20:16:57Z")

</div>

unknown wrote:

> On Mar 14, 11:40 am, removed\_email\_address@domain.invalid wrote:
> 
> > irb\> 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.

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [March 14, 2008, 9:08pm UTC](https://www.ruby-forum.com/t/how-to-separate-stdout-stderr-from-executed-shell-command/131964/4 "2008-03-14T21:08:28Z")

</div>

On Mar 14, 12:16 pm, Rodrigo B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> > 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?

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [March 14, 2008, 9:57pm UTC](https://www.ruby-forum.com/t/how-to-separate-stdout-stderr-from-executed-shell-command/131964/5 "2008-03-14T21:57:35Z")

</div>

On Mar 14, 12:58 pm, James G. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > > > > =\> [“”, “ls: NON\_existant\_file: No such file or directory\n”, 2]  
> > > > > The Pickaxe book has some good examples.  
> > > > > Any other pointers?
> 
> ```
> The parameter cmd is passed directly to Kernel#exec.
> 
> ```
> 
> Hope that helps.
> 
> James Edward G. II

Exactly what I was looking for. Thanks!

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [March 14, 2008, 11:18pm UTC](https://www.ruby-forum.com/t/how-to-separate-stdout-stderr-from-executed-shell-command/131964/6 "2008-03-14T23:18:11Z")

</div>

Hi,

require “open3”

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

Try it!

Arlen

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [March 14, 2008, 9:12pm UTC](https://www.ruby-forum.com/t/how-to-separate-stdout-stderr-from-executed-shell-command/131964/7 "2008-03-14T21:12:00Z")

</div>

On Mar 14, 2008, at 2:49 PM, removed\_email\_address@domain.invalid wrote:

> > > PS: Unless there’s a simpler way, if someone could just point me  
> > > 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 G. II
