[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Two way communication with the command shell (IO.popen?

James Smith

11/8/2006 12:54:00 AM



Hi,

I would basically like to be able to run a ruby program from my rails
application and be able to read from it and write to it accordingly.

OK, i am currently using:

IO.popen("ruby ruby_program.rb", "r+") do |f|
@read = f.read
@write = f.write #this is where i need help
end

say if the external ruby program was as follows:

0 def readWrite
1 puts "printing.."
2 @string = gets
3 end
4 readWrite

I can currently read (in example) "printing..", however when it reaches
line 2 of the ruby program, i can't seem to write to it, and my rails
program just waits. I need to use something that says "read from program
until it is waiting for input, and then write to it" (also, when writing
to the program, how do i emulate the user pressing enter - \n? )

Thanks


--
Posted via http://www.ruby-....

18 Answers

Ara.T.Howard

11/8/2006 2:31:00 AM

0

James Smith

11/8/2006 11:18:00 AM

0

unknown wrote:
> On Wed, 8 Nov 2006, James Smith wrote:
>
>> end
>> line 2 of the ruby program, i can't seem to write to it, and my rails
>> program just waits. I need to use something that says "read from program
>> until it is waiting for input, and then write to it" (also, when writing
>> to the program, how do i emulate the user pressing enter - \n? )
>>
>> Thanks
>
> this is a terrifically bad idea, but here's how you'd do it
>
>
> harp:~ > cat a.rb
> IO.popen("ruby ruby_program.rb", "r+") do |f|
> @read = f.gets
> p @read
> @write = f.puts 42
> end
>
> harp:~ > cat ruby_program.rb
> STDOUT.sync = true
>
> def readWrite
> puts "printing.."
> @string = gets
> end
>
> readWrite
>
>
> harp:~ > ruby a.rb
> "printing..\n"
>
>
> you were calling read, which reads till the end of input and that's not
> going
> to occur until the program exits.
>
> i highly reccomend post exatly what you are trying to accomplish so we
> can try
> to come up with a safer solution: spawning processes from a web-app like
> this
> will cause problems unless you are __very__ comfortable with ipc.
>
> cheers.
>
> -a

Thank you very much for your comments. I am basically writing a web
application where users can write and save ruby programs; then run them
on the server. I am at the stage where the user can save their programs
onto the server, however i now need to be able to input and recieve
output from them, as well as error messages. I am fairly certain i will
need to create a new thread for each of these processes, and probably
have a timeout on each of them.

Any help on this would be very much appreciated. Are there any sources
that you'd recommend me looking at?

--
Posted via http://www.ruby-....

Ara.T.Howard

11/8/2006 2:33:00 PM

0

James Smith

11/10/2006 10:28:00 AM

0

unknown wrote:
> On Wed, 8 Nov 2006, James Smith wrote:
>
>> Thank you very much for your comments. I am basically writing a web
>> application where users can write and save ruby programs; then run them on
>> the server. I am at the stage where the user can save their programs onto
>> the server, however i now need to be able to input and recieve output from
>> them, as well as error messages. I am fairly certain i will need to create a
>> new thread for each of these processes, and probably have a timeout on each
>> of them.
>
> ah. you really need to do be able to do this then
>
>> Any help on this would be very much appreciated. Are there any sources that
>> you'd recommend me looking at?
>
> sure, i think this already does everything you need:
>
> harp:~ > cat a.rb
> require 'open4'
>
> def gen_ruby_program path = 'b.rb'
> open path, 'w' do |f|
> f.write <<-src
> puts "what's your name?"
> name = gets
> puts("hi %s!" % name)
> src
> end
> path
> end
>
> program = gen_ruby_program
>
> stdin, stdout, stderr = "zaphod", "", ""
> timeout = 42
>
> status =
> open4.spawn "ruby #{ program }", :stdin=>stdin, :stdout=>stdout,
> :stderr=>stderr, :timeout=>timeout
>
> puts "status: #{ status.inspect }"
> puts "stdout: #{ stdout.inspect }"
> puts "stderr: #{ stderr.inspect }"
> harp:~ > ruby a.rb
> status: #<Process::Status: pid=8456,exited(0)>
> stdout: "what's your name?\nhi zaphod!\n"
> stderr: ""
>
>
> if you are on windows you'll want to use systemu instead of open4.
>
> -a

Hello again,

Thanks once again for your comments. OK i started off by installing
'systemu' (i am on windows). But i am struggling to understand your
code, and i can't work out if the external ruby program is included or
not. What i would like is for the user program to be completely seperate
from the rails, so the user doesn't know anything about the rails
program. Obviously when writing the users ruby program to file i can add
some lines of code if necessary. Then i would just like the rails
program to execute the users program (using its own thread??). This will
mean it reading any output from the users program and if it is waiting
for input, notify the rails program (eventually i will now display a
dialog allowing the user to input) and the rails program writes to it.
Then exit the thread after a timeout (if necessary) and print any
errors. So i just it to behave as though i was running the program on
the command line.
If this is wat the code above does, then could you please just explain
it to me please. Thank you once again.

jamie


--
Posted via http://www.ruby-....

James Smith

11/12/2006 6:32:00 PM

0

OK, keeping it simple I am basically using the following code:

IO.popen("ruby my_program.rb", "r+") do |f|

while(process hasn't finished) # need ruby code for this

read = f.gets
while(read != nil)
print read
read = f.gets
end

while(waiting for input) #need ruby code for this
write "xyz"
end

end
end


- I need to be able to test whether or not the ruby program is waiting
for input
- I would also like to be able to test whether or not the program has
finished running

Can anybody help me please.

--
Posted via http://www.ruby-....

Patrick Hurley

11/12/2006 6:39:00 PM

0

On 11/12/06, James Smith <jmdjmsmith@msn.com> wrote:
> OK, keeping it simple I am basically using the following code:
>
> IO.popen("ruby my_program.rb", "r+") do |f|
>
> while(process hasn't finished) # need ruby code for this
>
> read = f.gets
> while(read != nil)
> print read
> read = f.gets
> end
>
> while(waiting for input) #need ruby code for this
> write "xyz"
> end
>
> end
> end
>
>
> - I need to be able to test whether or not the ruby program is waiting
> for input
> - I would also like to be able to test whether or not the program has
> finished running
>
> Can anybody help me please.
>
> --
> Posted via http://www.ruby-....
>
>

This varies by platform a little, what os are you using?

pth

James Smith

11/12/2006 10:01:00 PM

0


>
> This varies by platform a little, what os are you using?
>
> pth


Windows. Any help would be great.. any ideas?

--
Posted via http://www.ruby-....

James Smith

11/13/2006 8:53:00 PM

0

Whats happened to my helpers?

--
Posted via http://www.ruby-....

Matthew Williams

11/16/2006 3:12:00 PM

0

> - I need to be able to test whether or not the ruby program is waiting
> for input
> - I would also like to be able to test whether or not the program has
> finished running

I'm not sure how to do this directly, or if this is even possible in
Ruby, however what you could do is to insert wrapper code into your user
programs. This code could override existing methods and take over the
input and output for the user programs. When the programs were then
waiting for input from the user, they would then call the wrapper code
and this could then indicate to the rails program that the users Ruby
program was waiting on input.

hope this helps, matt

--
Posted via http://www.ruby-....

Matthew Williams

11/16/2006 5:53:00 PM

0


> I'm not sure how to do this directly, or if this is even possible in
> Ruby,


I refuse to accept that this is not possible in Ruby (although I still
am unable to do this neatly). Can someone PLEASE shed some light, this
has caused me soo much anguish..

..in case you don't want to read though the posts then i would like to
know the following:

- I am running a Ruby program from my Rails application using:

> thread = Thread.new do
> IO.popen("ruby my_program.rb", "r+") do |pipe|
> while !pipe.eof
> NOW - I NEED TO KNOW HOW TO CHECK IF THE RUBY PROGRAM IS WAITING FOR INPUT

..i can read from it by reading and then checking if this returns 'nil';
if it is not equal to 'nil' then i will print it. i.e. i am trying to
simulate the behaviour of a standard command prompt. BUT i cannot check
if i need to write something to the program.

NOTE: all Ruby programs have "STDOUT.sync = true" in them.

Any ideas?

--
Posted via http://www.ruby-....