El SáÃado, 12 de Diciembre de 2009, Robert Klemme escribi > On 12.12.2009 10:53, Iki Baz Castillo wrote: > > El SáÃado, 12 de Diciembre de 2009, David Masover escribi > >> On Friday 11 December 2009 05:33:06 pm Iki 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 onlyanted 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. Thanks a lot! -- Iki Baz Castillo <ibc / aliax.net>