# Redirecting the end of a pipe

**URL:** <https://www.ruby-forum.com/t/redirecting-the-end-of-a-pipe/190713>\
**Category:** Ruby\
**Created:** [June 25, 2010, 3:34pm UTC](https://www.ruby-forum.com/t/redirecting-the-end-of-a-pipe/190713 "2010-06-25T15:34:05Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [June 25, 2010, 3:34pm UTC](https://www.ruby-forum.com/t/redirecting-the-end-of-a-pipe/190713/1 "2010-06-25T15:34:05Z")

</div>

Following interesting problem:

1. I have created two pipe end points via IO.pipe:  
stdin\_read,stdin\_write=IO.pipe

2. I have forked of a child, and redirected stdin of the child with:  
$stdin.reopen(stdin\_read)

3. In the parent process, I have used the other end of the pipe to write  
to the stdin of the child:  
stdin\_write.puts “word1”

At that point, I am finished sending stuff through the pipe  
automatically.  
However, I am unsure whether my child may need any further input.  
Because of that, I want to redirect the pipe end ‘stdin\_write’ in the  
parent to stdin, so that stuff coming in through stdin gets send on  
through stdin\_write (thus ending up in the stdin of the child).  
Question: How do I do that?

The obvious first try of stdin\_write.reopen($stdin) does not work, as it  
destroys the pipe connection.  
Of course I could just keep polling $stdin, and send anything I get on  
to stdin\_write, but really, ughh…

Does anybody have a nicer solution or idea?

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [June 25, 2010, 4:24pm UTC](https://www.ruby-forum.com/t/redirecting-the-end-of-a-pipe/190713/2 "2010-06-25T16:24:55Z")

</div>

2010/6/25 Thomas S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> Of course I could just keep polling $stdin, and send anything I get on  
> to stdin\_write, but really, ughh…
> 
> Does anybody have a nicer solution or idea?

You cannot solve this by redirection because $stdin is opened in read  
mode while stdin\_write is opened in write mode. You need something in  
between that sends over data. Any other solution works only if you  
can control the child’s code because then you can simply read from the  
pipe and continue reading from the old stdin which is inherited. Even  
for the temporary saving of the fd (what I did with “x” below) you  
need to control the child’s code.

#!/bin/env ruby19

rd, wr = IO.pipe

pid = fork do  
wr.close

# x = $stdin.clone

$stdin.reopen rd

$stdin.each\_line do |line|  
puts “child got: #{line}”  
end

false and x.each\_line do |line|  
puts “child got: #{line}”  
end  
end

rd.close

5.times do |i|  
wr.puts “parent sends #{i}”  
end

# line wise

false and $stdin.each\_line do |line|  
wr.puts “from stdin #{line}”  
end

# raw

while buffer = $stdin.read(100)  
wr.write(buffer)  
end

wr.close

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [June 28, 2010, 3:09pm UTC](https://www.ruby-forum.com/t/redirecting-the-end-of-a-pipe/190713/3 "2010-06-28T15:09:45Z")

</div>

Thank you for your answer.

I’ve now done precisely what I had hoped to avoid: Keep polling for new  
input, and pass on anything I get. As I don’t control the child,  
apparently the only thing I can do. At least it works…

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [June 28, 2010, 4:50pm UTC](https://www.ruby-forum.com/t/redirecting-the-end-of-a-pipe/190713/4 "2010-06-28T16:50:48Z")

</div>

2010/6/28 Thomas S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> Thank you for your answer.

You’re welcome.

> I’ve now done precisely what I had hoped to avoid: Keep polling for new  
> input, and pass on anything I get. As I don’t control the child,  
> apparently the only thing I can do. At least it works…

IMHO “polling” is not exactly the right term for this. Rather you  
read and block until more data is available - unless you use non  
blocking IO.

Kind regards

robert
