From: Robert Klemme Date: 2009-12-13T01:28:30+09:00 Subject: Re: Is it possible to force a Ruby program to run as a proc name different than "ruby"? On 12.12.2009 10:53, Iñaki Baz Castillo wrote: > El Sábado, 12 de Diciembre de 2009, David Masover escribió: >> On Friday 11 December 2009 05:33:06 pm Iñaki Baz Castillo wrote: >>> The good point of using: >>> >>> start-stop-daemon --stop --pidfile /var/run/rb_program.pid --name >>> rb_program >>> >>> is that it would stop the process just if it's called "rb_program" and >>> its pid matches the value of /var/run/rb_program.pid, so you cannot kill >>> any other process using that pid by accident (it could occur if your >>> program didn't delete the pidfile and a new process has taken same pid >>> value). >> That's a good point -- though I would guess that in theory, it shouldn't be >> possible for a program to die in such a way that it wouldn't be able to >> delete that file. The only thing that would make sense is a reboot, and on >> my system, /var/run is a tmpfs (only exists in RAM/swap), so it's not >> stored anywhere that would survive a reboot. > > Well, usually daemons are coded to deelte the pidfile upon receipt of a SIGINT > signal (or some others). But if the daemon is killed with "kill -9 PID" then > it terminates inmediately without deleting the piddile. > > In the case of a crash or segmentfault the daemon wouldn't delete the pidfile > again. > > I've coded my Debian init script "start" action so it deletes the existing > "pidfile" if it exists (it shouldn't). You can make deletion conditionally depending on the presence of the process (kill 0). This is what I would do: VAR='/var/run' pid_file = File.join(VAR, File.basename($0) + '.pid') begin old_pid = File.read(pid_file).to_i Process.kill 0, old_pid $stderr.puts "ERROR: already running with PID #{old_pid}" exit 1 rescue Errno::ENOENT # no pid file rescue Errno::ESRCH # process not running $stderr.puts 'WARNING: stale pid file' end # open file with EXCL in order to catch race conditions where two # processes were started almost at the same time and both thought # they would be a new instance. Uncomment sleep to simulate: # sleep 2 File.open(pid_file, File::EXCL | File::WRONLY | File::CREAT) {|io| io.write($$)} trap(0) {File.delete pid_file} puts "OK, here we go." # just for testing purposes: File.read(pid_file).to_i == $$ or raise "What went wrong?" sleep 10 puts "Finished" > Thanks a lot for all your suggestions, it's a really interesting subject. > However I would prefer to keep the code as simple as possible. The only I > wanted was the possibility of kill my program using "killall rb_program". Why does it have to be "killall"? What about providing a command line option "-k" or "--kill" for killing (e.g. as ssh-agent does)? You could integrate that pretty easily with the PID handling code above. > To summarize this is possible in these cases: > > a) Hardcoding the ruby location (avoiding using "env"). > Not user-friendly. I personally do not find it too unfriendly to place the interpreter name with an absolute path in the script. This has also greater safety and robustness: the one installing the program and ruby interpreter (some person with administrative permissions) is likely the same and can ensure location is set properly. Relying on users' environments is more fragile IMHO. > b) Creating a link "rb_program" to ruby interpreter and invoke my program with > "rb_program /PATH_TO_rb_program.rb". > Not very beauty :) > > c) Replacing env with your above suggestion. > It involves compiling a C program, it could break something in a not pure > Linux environment... > > Well, I've learnt *a lot* in this thread but at this point I think is better > just to leave the code as it is. > Really thanks a lot. Well, it's your choice. Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/