# Using popen with 0,1,2,3,4 streams

**URL:** <https://www.ruby-forum.com/t/using-popen-with-0-1-2-3-4-streams/121888>\
**Category:** Ruby\
**Created:** [December 2, 2007, 12:12pm UTC](https://www.ruby-forum.com/t/using-popen-with-0-1-2-3-4-streams/121888 "2007-12-02T12:12:39Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jan\_Koprowski](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/c5a1d2/32.png) [@Jan\_Koprowski](https://www.ruby-forum.com/u/Jan_Koprowski)\
**Post date:** [December 2, 2007, 12:12pm UTC](https://www.ruby-forum.com/t/using-popen-with-0-1-2-3-4-streams/121888/1 "2007-12-02T12:12:39Z")

</div>

Hi !

I try to run command system and get streams handlers to 0 (stdin),  
1(stdout), 2(stderr), 3(myOwnStdIn1), 4(myOwnStdIn2). I do something  
like that in PHP by proc\_open and table of pipes, but here I don’t  
know how I can get handlers to process streams. I know that this code  
is bad but I think something like this:

process = popen(‘command’, ‘w+’);  
stdin = process.new(0, “w”);  
stdout = process.new(1, “r”);

etc…

But new is a static method. What i should to do ?

---

<div class="post-metadata">

**Author:** ![Jan\_Koprowski](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/c5a1d2/32.png) [@Jan\_Koprowski](https://www.ruby-forum.com/u/Jan_Koprowski)\
**Post date:** [December 4, 2007, 1:33am UTC](https://www.ruby-forum.com/t/using-popen-with-0-1-2-3-4-streams/121888/2 "2007-12-04T01:33:52Z")

</div>

Jan,

You might look at popen3 in the standard library. I don’t think it  
quite  
does what you need (since it returns an array if three pipes: stdin,  
stdout  
and stderr for the subprocess) but the code is short if a little arcane,  
and  
might point you in the right direction to figure this out.

Judson

---

<div class="post-metadata">

**Author:** ![Jan\_Koprowski](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/c5a1d2/32.png) [@Jan\_Koprowski](https://www.ruby-forum.com/u/Jan_Koprowski)\
**Post date:** [December 4, 2007, 6:22pm UTC](https://www.ruby-forum.com/t/using-popen-with-0-1-2-3-4-streams/121888/3 "2007-12-04T18:22:50Z")

</div>

On Dec 3, 2007 5:32 PM, Judson L. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> On Dec 2, 2007 3:10 AM, Jan Koprowski [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > stdin = process.new(0, “w”);  
> > stdout = process.new(1, “r”);
> > 
> > etc…
> > 
> > But new is a static method. What i should to do ?

Also take a look at open4 and systemu. You can find both at the  
codeforpeople project on RubyForge. They, too, will offer some good  
insight on what you want to do, though neither does precisely what you  
need.

[http://rubyforge.org/projects/codeforpeople](http://rubyforge.org/projects/codeforpeople)

Blessings,  
TwP

---

<div class="post-metadata">

**Author:** ![Jan\_Koprowski](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/c5a1d2/32.png) [@Jan\_Koprowski](https://www.ruby-forum.com/u/Jan_Koprowski)\
**Post date:** [December 6, 2007, 9:27am UTC](https://www.ruby-forum.com/t/using-popen-with-0-1-2-3-4-streams/121888/4 "2007-12-06T09:27:38Z")

</div>

On 4 Gru, 17:58, Tim P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > > is bad but I think something like this:  
> > > codeforpeople project on RubyForge. They, too, will offer some good  
> > > insight on what you want to do, though neither does precisely what you  
> > > need.
> 
> [http://rubyforge.org/projects/codeforpeople](http://rubyforge.org/projects/codeforpeople)
> 
> Blessings,  
> TwP

Thank You for respond. I know that I can use only 3 pipes. But I think  
I can look for open4 and try to write something similar. Thanks !

---

<div class="post-metadata">

**Author:** ![Jan\_Koprowski](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/c5a1d2/32.png) [@Jan\_Koprowski](https://www.ruby-forum.com/u/Jan_Koprowski)\
**Post date:** [December 6, 2007, 9:42am UTC](https://www.ruby-forum.com/t/using-popen-with-0-1-2-3-4-streams/121888/5 "2007-12-06T09:42:16Z")

</div>

On 4 Gru, 17:58, Tim P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > > is bad but I think something like this:  
> > > codeforpeople project on RubyForge. They, too, will offer some good  
> > > insight on what you want to do, though neither does precisely what you  
> > > need.
> 
> [http://rubyforge.org/projects/codeforpeople](http://rubyforge.org/projects/codeforpeople)
> 
> Blessings,  
> TwP

U try to write something like this:

# 

# To change this template, choose Tools | Templates

# and open the template in the editor.

require ‘fcntl’  
require ‘timeout’  
require ‘thread’

class Broker\_process3

READ = 0 # Consts to explicite mark read  
WRITE = 1 # and write pipes  
@stdin  
@stdout  
@stderr

def initialize

end

def self.run (command, params)  
pw, pr, pe, pl, pp = IO.pipe, IO.pipe, IO.pipe, IO.pipe, IO.pipe  
pl.last.fcntl(Fcntl::F\_SETFD, Fcntl::FD\_CLOEXEC)  
pp.last.fcntl(Fcntl::F\_SETFD, Fcntl::FD\_CLOEXEC)

```
pid = fork {
  pw.last.close
  STDIN.reopen pw.first
  pw.first.close

  pr.first.close
  STDOUT.reopen pr.last
  pr.last.close

  pe.first.close
  STDERR.reopen pe.last
  pe.last.close

  pl.last.close
  pp.last.close

  STDOUT.sync = STDERR.sync = true

  exec(*command)
}

[pw.first, pr.last, pe.last, pl.first, pp.first].each{|fd|

```

fd.close}

```
pl.last.write("login"); // ERROR HERE
pl.last.close
pp.last.write("has³o");
pp.last.close

pw.last.close
out = pr.first.readlines
pr.first.close
pe.first.close
puts out;

```

end  
end

but in // ERROR HERE I get:

./broker\_process3.rb:48:in `write': Broken pipe (Errno::EPIPE) from ./broker_process3.rb:48:in `run’  
from /home/johny/NetBeansProjects/zhradmin/lib/main.rb:12

---

<div class="post-metadata">

**Author:** ![Jan\_Koprowski](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/c5a1d2/32.png) [@Jan\_Koprowski](https://www.ruby-forum.com/u/Jan_Koprowski)\
**Post date:** [December 6, 2007, 9:43am UTC](https://www.ruby-forum.com/t/using-popen-with-0-1-2-3-4-streams/121888/6 "2007-12-06T09:43:27Z")

</div>

On 4 Gru, 17:58, Tim P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > > is bad but I think something like this:  
> > > codeforpeople project on RubyForge. They, too, will offer some good  
> > > insight on what you want to do, though neither does precisely what you  
> > > need.
> 
> [http://rubyforge.org/projects/codeforpeople](http://rubyforge.org/projects/codeforpeople)
> 
> Blessings,  
> TwP

U try to write something like this:

# 

# To change this template, choose Tools | Templates

# and open the template in the editor.

require ‘fcntl’  
require ‘timeout’  
require ‘thread’

class Broker\_process3

READ = 0 # Consts to explicite mark read  
WRITE = 1 # and write pipes  
@stdin  
@stdout  
@stderr

def initialize

end

def self.run (command, params)  
pw, pr, pe, pl, pp = IO.pipe, IO.pipe, IO.pipe, IO.pipe, IO.pipe  
pl.last.fcntl(Fcntl::F\_SETFD, Fcntl::FD\_CLOEXEC)  
pp.last.fcntl(Fcntl::F\_SETFD, Fcntl::FD\_CLOEXEC)

```
pid = fork {
  pw.last.close
  STDIN.reopen pw.first
  pw.first.close

  pr.first.close
  STDOUT.reopen pr.last
  pr.last.close

  pe.first.close
  STDERR.reopen pe.last
  pe.last.close

  pl.last.close
  pp.last.close

  STDOUT.sync = STDERR.sync = true

  exec(*command)
}

[pw.first, pr.last, pe.last, pl.first, pp.first].each{|fd|

```

fd.close}

```
pl.last.write("login"); // ERROR HERE
pl.last.close
pp.last.write("has³o");
pp.last.close

pw.last.close
out = pr.first.readlines
pr.first.close
pe.first.close
puts out;

```

end  
end

but in // ERROR HERE I get:

./broker\_process3.rb:48:in `write': Broken pipe (Errno::EPIPE) from ./broker_process3.rb:48:in `run’  
from /home/johny/NetBeansProjects/zhradmin/lib/main.rb:12
