# IO.popen('-') === fork?

**URL:** <https://www.ruby-forum.com/t/io-popen-fork/180810>\
**Category:** Ruby\
**Created:** [December 29, 2009, 6:26pm UTC](https://www.ruby-forum.com/t/io-popen-fork/180810 "2009-12-29T18:26:46Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![nilezparker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/a3d4f5/32.png) [@nilezparker](https://www.ruby-forum.com/u/nilezparker)\
**Post date:** [December 29, 2009, 6:26pm UTC](https://www.ruby-forum.com/t/io-popen-fork/180810/1 "2009-12-29T18:26:46Z")

</div>

I just want to know if the following two are technically equivalent  
(calling fork(2) in UNIX environments):

##########

IO.popen(’-’) {|io|  
…  
}

#---------

fork do  
…  
end

##########

As much explanation you want to give will be appreciated, I will soak it  
all up. Thanks ahead. 🙂

---

<div class="post-metadata">

**Author:** ![nilezparker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/a3d4f5/32.png) [@nilezparker](https://www.ruby-forum.com/u/nilezparker)\
**Post date:** [December 29, 2009, 9:20pm UTC](https://www.ruby-forum.com/t/io-popen-fork/180810/2 "2009-12-29T21:20:42Z")

</div>

2009/12/29 Nilez P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> fork do  
> …  
> end
> 
> ##########
> 
> As much explanation you want to give will be appreciated, I will soak it  
> all up. Thanks ahead. 🙂

fork does nothing to redirect stdin, stdout and stderr while popen in  
the form you used will send the sub process’s stdout to a pipe. So  
the answer is: no, they are not equivalent. Rather popen uses some  
form of fork under the hood.

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![nilezparker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/a3d4f5/32.png) [@nilezparker](https://www.ruby-forum.com/u/nilezparker)\
**Post date:** [December 29, 2009, 9:53pm UTC](https://www.ruby-forum.com/t/io-popen-fork/180810/3 "2009-12-29T21:53:52Z")

</div>

> fork does nothing to redirect stdin, stdout and stderr while popen in  
> the form you used will send the sub process’s stdout to a pipe. So  
> the answer is: no, they are not equivalent. Rather popen uses some  
> form of fork under the hood.

Thanks Robert. I think I meant to ask whether Process.popen uses the  
same OS fork call as Process.fork does.

I found what I need for now though, so I’m posting it partly just for  
people who find this via google later on. I wanted some pipes between  
parent and children, and this is what I came up with:

children = []  
3.times do  
from\_child, to\_parent = IO.pipe  
from\_parent, to\_child = IO.pipe  
fork do  
# don’t need to read from or write to child  
to\_child.close  
from\_child.close  
to\_parent.write “READY”  
loop { … }  
end  
children \<\< to\_child  
# don’t need to read from or write to parent  
to\_parent.close  
from\_parent.close  
end

# Now the parent has a read/write IO pair for each child stored in

`children’; each child has a read/write IO pair for the parent.

Thanks Robert for the quick answer, and I’m still curious whether  
Process.popen uses the same OS fork call as Process.fork does.

---

<div class="post-metadata">

**Author:** ![nilezparker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/a3d4f5/32.png) [@nilezparker](https://www.ruby-forum.com/u/nilezparker)\
**Post date:** [December 29, 2009, 10:15pm UTC](https://www.ruby-forum.com/t/io-popen-fork/180810/4 "2009-12-29T22:15:43Z")

</div>

On 12/29/2009 09:54 PM, Nilez P. wrote:

> parent and children, and this is what I came up with:  
> loop { … }  
> end  
> children \<\< to\_child  
> # don’t need to read from or write to parent  
> to\_parent.close  
> from\_parent.close  
> end
> 
> # Now the parent has a read/write IO pair for each child stored in
> 
> `children’; each child has a read/write IO pair for the parent.

I don’t see why you go through this instead using one of the #popen  
family of methods (there is also #popen3).

> Thanks Robert for the quick answer, and I’m still curious whether  
> Process.popen uses the same OS fork call as Process.fork does.

Underneath it is eventually the same, yes.

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![nilezparker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/a3d4f5/32.png) [@nilezparker](https://www.ruby-forum.com/u/nilezparker)\
**Post date:** [December 30, 2009, 12:03am UTC](https://www.ruby-forum.com/t/io-popen-fork/180810/5 "2009-12-30T00:03:37Z")

</div>

> I don’t see why you go through this instead using one of the #popen  
> family of methods (there is also #popen3).

Thanks again … but I’ve looked around at the docs and I don’t see how I  
could accomplish the same thing as my example code. Perhaps the main  
problem is that with popen\* the parent process goes into the block too,  
and its pipes with the child are closed when it leaves the block. This  
is a problem because I need to start several child forks and be able to  
communicate with them all, and then start and stop them at will from  
there. Any pointers as to how I can / should use popen, or popen2, or  
popen3?

---

<div class="post-metadata">

**Author:** ![nilezparker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/a3d4f5/32.png) [@nilezparker](https://www.ruby-forum.com/u/nilezparker)\
**Post date:** [December 30, 2009, 12:16am UTC](https://www.ruby-forum.com/t/io-popen-fork/180810/6 "2009-12-30T00:16:18Z")

</div>

On Dec 29, 2009, at 6:03 PM, Nilez P. wrote:

> popen3?  
> If you don’t pass a block to IO#popen, it just returns the IO object.  
> popen3() works similarly.

Gary W.
