You want to run a process in the background with minimal interference from users and the operating system.
In Ruby 1.9, you can simply call Process.daemon to turn the current process into a daemon. Otherwise, the most reliable way is to use the Daemonize module. Its not available as a gem, but its worth downloading and installing, because it makes it easy and reliable to write a daemon:
#!/usr/bin/ruby -w # daemonize_daemon.rb require empfile require daemonize include Daemonize # Import Daemonize::daemonize into this namespace puts About to daemonize. daemonize # Now you e a daemon process! log = Tempfile.new(daemon.log) loop do log.puts "Im a daemon, doin daemon things." log.flush sleep 5 end
If you run this code at the command line, youll get back a new prompt almost immediately. But there will still be a Ruby process running in the background, writing to a temporary file every five seconds:
$ ./daemonize_daemon.rb About to daemonize. $ ps x | grep daemon 4472 ? S 0:00 ruby daemonize_daemon.rb 4474 pts/2 S+ 0:00 grep daemon $ cat /tmp/daemon.log4472.0 Im a daemon, doin daemon things. Im a daemon, doin daemon things. Im a daemon, doin daemon things.
Since it runs an infinite loop, this daemon process will run until you kill it:
$ kill 4472 $ ps x | grep daemon 4569 pts/2 S+ 0:00 grep daemon
A different daemon might run until some condition is met, or until it receives a Unix signal, or a "stop" message through some interface.
A daemon process is one that runs in the background, without any direct user interface at all. Servers are usually daemon processes, but you might also write a daemon to do monitoring or task scheduling.
Rather than replacing your process with a daemon process, you may want to spawn a daemon while continuing with your original work. The best strategy for this is to spawn a subprocess with Kernel#fork.
Rubys fork implementation takes a code block to be run by the subprocess. The code defined after the block is run in the original process. So pass your daemonizing code into fork, and continue with your work in the main body of the code:
#!/usr/bin/ruby -w # daemon_spawn.rb require empfile require daemonize include Daemonize puts "About to daemonize." fork do daemonize log = Tempfile.new(daemon.log) loop do log.puts "Im a daemon, doin daemon things." log.flush sleep 5 end end puts The subprocess has become a daemon. puts "But Im going to stick around for a while." sleep 10 puts "Okay, now Im done."
The Daemonize code fits in a single file, and its licensed under the same terms as Ruby. If you don want to require your users to download and install it, you can just include it with your program. Because the code is short, you can even copy-and-paste the code into a file in your own program.
However, theres also some (less fancy) daemonizing code in the Ruby 1.8 standard library. Its the WEBrick::Daemon class.
#!/usr/bin/ruby # webrick_daemon.rb require empfile require webrick puts About to daemonize. WEBrick::Daemon.start do log = Tempfile.new(daemon.log) loop do log.puts "Im a daemon, doin daemon things." log.flush sleep 5 end end
Its worth examining the simpler daemonizing code in WEBrick::Daemon so that you can see whats going on. Heres the method in question:
def Daemon.start exit!(0) if fork Process::setsid exit!(0) if fork Dir::chdir("/") File::umask(0) STDIN.reopen("/dev/null") STDOUT.reopen("/dev/null", "w") STDERR.reopen("/dev/null", "w") yield if block_given? end
A daemonizer works by forking a new process, letting the original one die, and closing off some of the resources that were available to the original.
Process::setsid disconnects the daemon from the terminal that spawned it. This is why, when your process becomes a daemon process, you get your command line back immediately. We close the original standard input, output, and error and replace them with null streams. We set the working directory and file umask to sensible defaults, regardless of what the daemon inherited from the parent. Then we run the daemon code.
Daemonize::daemonize also sets up signal handlers, calls srand so that the daemon process has a new random number seed, and (optionally) closes any open file handles left around by the original process. It can also retry the fork if it fails because the operating system is running too many processes to create another one.
The fork method, and methods like daemonize that depend on it, are only available on Unix-like systems. On Windows, the win32-process extension provides Windows implementations of methods like fork. The win32-process implementation of fork isn perfect, but its there if you need it. For cross-platform code, we recommend you spawn a thread and run your daemon code in the thread.
Strings
Numbers
Date and Time
Arrays
Hashes
Files and Directories
Code Blocks and Iteration
Objects and Classes8
Modules and Namespaces
Reflection and Metaprogramming
XML and HTML
Graphics and Other File Formats
Databases and Persistence
Internet Services
Web Development Ruby on Rails
Web Services and Distributed Programming
Testing, Debugging, Optimizing, and Documenting
Packaging and Distributing Software
Automating Tasks with Rake
Multitasking and Multithreading
User Interface
Extending Ruby with Other Languages
System Administration