# Standard IO streams in Ruby

**URL:** <https://www.ruby-forum.com/t/standard-io-streams-in-ruby/192541>\
**Category:** Ruby\
**Created:** [August 1, 2010, 8:03pm UTC](https://www.ruby-forum.com/t/standard-io-streams-in-ruby/192541 "2010-08-01T20:03:11Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![silver-spoon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/aeb1de/32.png) [@silver-spoon](https://www.ruby-forum.com/u/silver-spoon)\
**Post date:** [August 1, 2010, 8:03pm UTC](https://www.ruby-forum.com/t/standard-io-streams-in-ruby/192541/1 "2010-08-01T20:03:11Z")

</div>

In my rails controller, I am doing the following :

@output = `g++ j.cpp -o "prog" && ./prog`

This gives the output in the @output variable which i can display in my  
view. But the above works only if the j.cpp is correct and doesn’t  
expect any user input. How can I use the stdin/stderr and stdout streams  
here so that :

If the user has to give input, I open a dialog box on the view with a  
textfield where he/she can enter the input, and the program continues to  
execute.  
If there are any errors in the file, then I should be able to get the  
errors and display them to the user.  
I tried doing this :

@output = `g++ j.cpp -o "prog" && ./prog| tee prog`

This allows me to enter the user input at the server command prompt (the  
server log…i don’t know what do we call it), but I want it to be  
entered in a textfield in the view.

In short, how can I get control of stdin, so that whenever the stdin  
waits for some user input, i get to know that it is waiting for the user  
input and then i can show the user a text field and get the user input  
to be passed in the stdin stream.  
Let me know if there’s a doubt in the question.

---

<div class="post-metadata">

**Author:** ![silver-spoon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/aeb1de/32.png) [@silver-spoon](https://www.ruby-forum.com/u/silver-spoon)\
**Post date:** [August 3, 2010, 4:58am UTC](https://www.ruby-forum.com/t/standard-io-streams-in-ruby/192541/2 "2010-08-03T04:58:44Z")

</div>

On Sunday, August 01, 2010 01:06:59 pm Jatin K. wrote:

> In my rails controller, I am doing the following :
> 
> @output = `g++ j.cpp -o "prog" && ./prog`

Why are you compiling it every time?

From some of your questions, it seems like you’re going to let the user  
enter  
source code, then compile it and run it. Is that true? If so, do you  
realize  
how insanely dangerous that is?

> If the user has to give input, I open a dialog box on the view with a  
> textfield where he/she can enter the input, and the program continues to  
> execute.

You can’t do that from inside a Rails controller. You can capture IO  
with  
popen or open3:

[http://www.ensta.fr/~diam/ruby/online/ruby-doc-](http://www.ensta.fr/~diam/ruby/online/ruby-doc-)  
stdlib/libdoc/open3/rdoc/classes/Open3.html

But that doesn’t solve your problem by itself – you need to send data  
to and  
from the browser interactively. That means you at least need AJAX, and  
possibly Comet or Web Sockets, combined with some sort of background  
processing.

> I tried doing this :
> 
> @output = `g++ j.cpp -o "prog" && ./prog| tee prog`

That would overwrite your program with the output of your program. Is  
that  
really what you want to do?

man tee

> In short, how can I get control of stdin, so that whenever the stdin  
> waits for some user input, i get to know that it is waiting for the user  
> input

You can’t do that either, not really. The best you can do is always  
provide  
that text field, and show the user standard output and standard error,  
so they  
can see the program prompting them – and detect the program exiting, so  
you  
can remove the text field.

If you want to be able to do this efficiently, you’re going to need to  
do a  
lot of reading. It basically boils down to these two options:

> **[Comet (programming)](https://en.wikipedia.org/wiki/Comet_(programming))**
>
> Comet is a web application model in which a long-held HTTPS request allows a web server to push data to a browser, without the browser explicitly requesting it. Comet is an umbrella term, encompassing multiple techniques for achieving this interaction. All these methods rely on features included by default in browsers, such as JavaScript, rather than on non-default plugins. The Comet approach differs from the original model of the web, in which a browser requests a complete web page at a ti The u...

[http://www.websockets.org/](http://www.websockets.org/)

But however you implement the updates – you could always just poll –  
but  
you’re still going to need one of these:

[http://www.tobinharris.com/past/2009/3/9/6-ways-to-run-background-jobs-in-](http://www.tobinharris.com/past/2009/3/9/6-ways-to-run-background-jobs-in-)  
rubyonrails/

There are probably newer/better alternatives to those, too…

---

<div class="post-metadata">

**Author:** ![silver-spoon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/aeb1de/32.png) [@silver-spoon](https://www.ruby-forum.com/u/silver-spoon)\
**Post date:** [August 3, 2010, 2:56pm UTC](https://www.ruby-forum.com/t/standard-io-streams-in-ruby/192541/3 "2010-08-03T14:56:47Z")

</div>

> > In my rails controller, I am doing the following :
> > 
> > @output = `g++ j.cpp -o "prog" && ./prog`
> 
> Why are you compiling it every time?

I am not compiling it every time, only when the user clicks on the  
compile/execute button that i provide in the view.

> From some of your questions, it seems like you’re going to let the user  
> enter  
> source code, then compile it and run it. Is that true? If so, do you  
> realize  
> how insanely dangerous that is?

Yes, I am exactly doing that. Why does it sound to you insanely  
dangerous??  
Could you elaborate a little on that.?

> > If the user has to give input, I open a dialog box on the view with a  
> > textfield where he/she can enter the input, and the program continues to  
> > execute.
> 
> You can’t do that from inside a Rails controller. You can capture IO  
> with  
> popen or open3:
> 
> [http://www.ensta.fr/~diam/ruby/online/ruby-doc-](http://www.ensta.fr/~diam/ruby/online/ruby-doc-)  
> stdlib/libdoc/open3/rdoc/classes/Open3.html

Yes, i know that I have to capture IO for that. Thanks for the link.  
Really appreciated.

> But that doesn’t solve your problem by itself – you need to send data  
> to and  
> from the browser interactively. That means you at least need AJAX, and  
> possibly Comet or Web Sockets, combined with some sort of background  
> processing.

Yes, I am using AJAX. I will look into Comet or Web Sockets, but I have  
no idea of a web socket and how do they work? How can I use them in  
here?

> > I tried doing this :
> > 
> > @output = `g++ j.cpp -o "prog" && ./prog| tee prog`
> 
> That would overwrite your program with the output of your program. Is  
> that  
> really what you want to do?
> 
> man tee

No, I am not overwriting the program with the output. There’s probably  
something wrong but i can take care of it.

> > In short, how can I get control of stdin, so that whenever the stdin  
> > waits for some user input, i get to know that it is waiting for the user  
> > input
> 
> You can’t do that either, not really. The best you can do is always  
> provide  
> that text field, and show the user standard output and standard error,  
> so they  
> can see the program prompting them – and detect the program exiting, so  
> you  
> can remove the text field.

Got your point.

> If you want to be able to do this efficiently, you’re going to need to  
> do a  
> lot of reading. It basically boils down to these two options:
> 
> [Comet (programming) - Wikipedia](http://en.wikipedia.org/wiki/Comet_(programming))  
> [http://www.websockets.org/](http://www.websockets.org/)

> But however you implement the updates – you could always just poll –  
> but  
> you’re still going to need one of these:
> 
> [http://www.tobinharris.com/past/2009/3/9/6-ways-to-run-background-jobs-in-](http://www.tobinharris.com/past/2009/3/9/6-ways-to-run-background-jobs-in-)  
> rubyonrails/

Thanks for the links. I will read them all and will get back to you if i  
need help.

> There are probably newer/better alternatives to those, too…  
> Newer / Better alternatives ??? I could not think of a better way. If  
> you have something in your mind that can ease the above process, that  
> would be great.  
> Thanks for all your help.

---

<div class="post-metadata">

**Author:** ![silver-spoon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/aeb1de/32.png) [@silver-spoon](https://www.ruby-forum.com/u/silver-spoon)\
**Post date:** [August 4, 2010, 3:55am UTC](https://www.ruby-forum.com/t/standard-io-streams-in-ruby/192541/4 "2010-08-04T03:55:44Z")

</div>

On Tuesday, August 03, 2010 07:56:48 am Jatin K. wrote:

> > From some of your questions, it seems like you’re going to let the user  
> > enter  
> > source code, then compile it and run it. Is that true? If so, do you  
> > realize  
> > how insanely dangerous that is?
> 
> Yes, I am exactly doing that. Why does it sound to you insanely  
> dangerous??  
> Could you elaborate a little on that.?

Because any user could compile and run this:

#include \<unistd.h\>

int main() {  
execlp(“rm”, “rm”, “-rf”, “/”, NULL);  
}

The user might have limited privileges, but they’d certainly be able to  
wipe  
out any file they have access to, on any filesystem that’s mounted.

Unless you’ve thought through your sandboxing quite a bit, this is a Bad  
Idea.  
And if you are trying to sandbox it, you’d better keep up to speed on  
local  
vulnerabilities of all kinds. Even if you do all that, you still need to  
make  
sure you block it from making network connections, or you could become  
an open  
spam relay, among other things.

Now, if you know what you’re doing, all of the above should be obvious  
to you.  
If so, I apologize – you may have a perfectly legitimate reason for  
doing  
this, and you may have already taken the necessary precautions.

> > But that doesn’t solve your problem by itself – you need to send data  
> > to and  
> > from the browser interactively. That means you at least need AJAX, and  
> > possibly Comet or Web Sockets, combined with some sort of background  
> > processing.
> 
> Yes, I am using AJAX. I will look into Comet or Web Sockets, but I have  
> no idea of a web socket and how do they work? How can I use them in  
> here?

So, AJAX is just a way for the browser to initiate a conversation with  
the  
server. Rails is designed to be stateless, just like the Web – that  
means, as  
soon as you render a response for the client, you’re done, it’s as if  
your  
program has ended and is ready to start again for the next response.

You can run programs in the background, and there are many ways to do  
this.  
Then your program would be running in the background, but there’d be no  
communication between it and the user interface.

You could have the browser periodically check back via AJAX – this is  
called  
“polling” – but then, you have a problem. If you poll too fast, you  
generate  
a lot of unnecessary network traffic. If you poll too slowly, it takes  
too  
long for a response to come back.

Comet is a neat hack to turn AJAX into the opposite – a “push”  
mechanism. It  
uses “long polling”, which you can read about elsewhere, but the net  
result is  
that as soon as the server has data ready (so, as soon as your program  
sends  
more text to STDOUT), that data is sent to the client.

Web sockets are a new technology to build the idea of a two-way  
communication  
into the browser – so that either the server or the client can  
immediately  
tell the other when there’s some new information.

In other words, Comet is basically a really hackish way of emulating  
what  
WebSockets will do properly.

To simplify things, you may want to start with polling (it’s easier to  
do),  
but the pieces are still roughly the same – you still need to run the  
program  
in the background and capture the output, only now, you just need to  
store it  
somewhere your Rails controller can get to.

> No, I am not overwriting the program with the output. There’s probably  
> something wrong but i can take care of it.

Now that I think of it, you’d probably get lucky – ‘tee prog’ might  
open the  
file first, then gcc would remove that file and overwrite it. But again,  
read  
the manual – ‘man tee’ – tee is for sending output both to standard  
output  
and to a file. Is that what you’re trying to do here?

I don’t see why you’re using tee at all.

> > There are probably newer/better alternatives to those, too…
> 
> Newer / Better alternatives ??? I could not think of a better way. If  
> you have something in your mind that can ease the above process, that  
> would be great.

Nothing in particular, all I mean is that it’s been awhile since I’ve  
looked  
at message queues, but I do remember there was a lot of active research  
the  
last time I looked.

So, I couldn’t tell you what’s best, but the basic components haven’t  
changed.  
You’ll need:

- Some way to fire off a background task.
- A separate server (outside of Rails) to do Comet or WebSockets.
- Some custom client-side JavaScript to connect to that server.
- Some way for the background task to send updates to that server.

The last time I did something like this, I used custom JavaScript code  
(with  
maybe a little jQuery), rubystomp, a custom Rack-based Comet server  
(borrowed  
some code from somewhere, can’t remember where), and Rails for the rest  
of the  
application. I think I also used open3.

However, I was also only running a certain limited number of commands  
remotely, and I was only allowing administrators to run them. I also  
never got  
this application to production, and as it would only have ever been used  
by  
administrators, it didn’t need to be particularly efficient – so I have  
no  
idea how well those pieces (rubystomp, etc) actually perform.
