Waley Chen
Waley Chen

Reputation: 929

Handling Input and Output of a Daemon

I want to create a daemon of a ruby program on Linux.

I also want the daemon to be interactive-I want to be able to send input to the daemon through a file/pipe/the simplest method and receive output to a file.

How do I go about doing this?

I've looked into the module daemons (http://daemons.rubyforge.org/), threads and the method popen3 but I'm having a hard time getting them to do the above.

ANSWER: Mladen's method:

I have the controller that creates the daemon: (you'll need the daemons module gem)

require 'rubygems'
require 'daemons'

Daemons.run('/myDaemon.rb', {:app_name => "o", :dir_mode => :normal, :dir => '', :log_output => true, :multiple => true })

Here's myDaemon.rb:

puts `pwd`

File.open('my_pipe', 'r+') do |f|
    loop do
            line = f.gets
            puts "Got: #{line}"
    end
end

Steps: Both files are in my root directory \. The Daemons.run creates the daemon in \.

  1. Create a named pipe, mkfifo ./my_pipe.

  2. ruby controller.rb start

  3. cat > my_pipe

  4. type text

  5. ctrl-c to stop input

  6. cat o.output to see your output

Upvotes: 4

Views: 2668

Answers (2)

Mladen Jablanović
Mladen Jablanović

Reputation: 44080

Probably the simplest way, named pipes, based on http://www.pauldix.net/2009/07/using-named-pipes-in-ruby-for-interprocess-communication.html:

Step 1: Create a named pipe

mkfifo ./my_pipe

Step 2: Create your "daemon":

File.open('my_pipe', 'r+') do |f|
  loop do
    line = f.gets
    puts "Got: #{line}"
  end
end

and run it.

Step 3: Open another terminal and run

cat > my_pipe

and start typing some text, line by line.

Step 4: Watch output of the daemon.

Step 5: ???

Step 6: Profit.

Upvotes: 4

unpythonic
unpythonic

Reputation: 4070

Open a socket bound to a port which is unused, but which is known to you and the program(s) which want to communicate with it. If the daemon only needs to talk with processes on the same machine, then use a Unix domain socket (see Socket.unix_server_loop). If it needs to also communicate with processes outside of the host it's running on, then you'll want to open an internet socket (see Socket.tcp_server_loop).

The general recipe for the server is:

  • Open a socket
  • Bind to the host's ip address and a selected port (tcp), or bind to a path on the system (unix)
  • Wait (select) for something to connect
  • Accept the connection
  • Enter read/write communication loop

On the client:

  • Open a socket
  • Connect to the address/port of the server, or connect to the path of the Unix domain socket the server is using
  • Once connected, enter the write/read communication loop.

Your server and client(s) need to agree on who sends what first and what the appropriate responses are by the other party.

Upvotes: 2

Related Questions