0

The console application I would like to control is Bluesoleil. It's a Bluetooth software/driver, but details of the software isn't that important I think. What I want to do is basically, type console commands in Windows or Linux terminal environment using web browser running Ruby on Rails app.

So high level design of the Ruby on Rails app would be something like this.

  • Web browser showing a page with UI for Bluesoleil
  • Ruby on Rails app render the page for UI, takes in commands from the user and displays result through web browser, just like regular Ruby on Rails app
  • On the backend, Ruby on Rails types in commands in the console that is running Bluesoleil. And the result shown in the console is grabbed as string by Ruby on Rails.

Is something like this possible with Ruby on Rails?

Just to clear possible confusion, when I say console and console application here, I don't mean Rails console or Ruby console. Console here is just a terminal environment running console applications and so on.

Thank you.

3
  • 2
    So you are simply asking how to execute shell commands? Use backticks or %x{ ... code here ... }. Commented Jan 19, 2012 at 21:44
  • @d11wtq Thanks! Do you know of any documentation on this? Commented Jan 19, 2012 at 21:48
  • 1
    like this? apidock.com/ruby/Kernel/system Commented Jan 19, 2012 at 21:56

1 Answer 1

2

If you only need to run a "one-off" command, just use backticks. If you need to maintain a long-running background process, which accepts commands and returns responses, you can do something like this (some of the details have been edited out, since this code is from a proprietary application):

class Backend
  def initialize
    @running = false
    @server  = nil
    # if we forget to call "stop", make sure to close down background process on exit
    ObjectSpace.define_finalizer(self,lambda { stop if @running })
  end

  def start
    stop if @running
    @server = IO.popen("backend","w+")
    @running = true
  end

  def stop
    return if not @running
    @server << "exit\n"
    @server.flush
    @running = false
 end

 def query(*args)
   raise "backend not running" if not @running
   @server << "details edited out\n"
   @server.flush
   loop do
     response = parse_response
     # handle response
     # break loop when backend is finished sending data
   end
 end

 private
   def parse_response
     # details edited out, uses c = @server.getc to read data from backend
     # getc will block if there is nothing to read,
     # so there needs to be an unambiguous terminator telling you where
     # to stop reading
   end
 end

end

You can adapt this to your own needs. Beware of situations where the background process dies and leaves the main process hanging.

Although it doesn't apply to your situation, if you are designing the background program yourself: Build the background process so that if ANYTHING makes it crash, it will send an unambiguous message like "PANIC" or something which tells the main process to either exit with an error message, or try starting another background process. Also, make sure it is completely unambiguous where each "message" begins and ends, and test the coordination between main/background process well -- if there are bugs on either end, it is very easy to get a situation where both processes get stuck waiting for each other. One more thing: design the "protocol" which the 2 processes speak to each other in a way which makes it easy to maintain synchronization between the 2.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.