On Thu, May 16, 2002 at 12:16:58PM -0700, Matt Simonsen wrote: > > My best guess is I should have the script immediately fork a copy of itself > then die while the forked copy still runs, but I haven't been able to figure > out how to make that work. Any suggestions would be helpful, especially a > sample loop like this that just forks a daemon to do something stupid like > print "foo" ; forever.
Ok, here's what we need to do to completely detach from our parent process - speak when we want to become a daemon: 1. get out of the parent's (in that case your shell's) process group. We'll have PPID 1 after this call. The only error that setsid can throw is EPERM which means that we already are process group leader. 2. move up to the root directory, so that we're not blocking filesystems that one might want to unmount (e.g. /opt) 3. close all those rotten filehandles who's output nobody will see anyways... ---------- daemonify ---------- #!/usr/bin/perl -w use strict; use POSIX qw/setsid/; my $child = shift; die "Path to $child must be absolute\n" unless $child =~ /^\//; unless (fork) { setsid(); chdir '/'; close STDIN; close STDOUT; close STDERR; exec $child; # or write your code here... die "Mustn't happen: exec failed: $!\n"; } # No need to reap since we detached... exit; ---------- daemonify ---------- and ---------- daemonified ---------- #!/usr/bin/perl use strict; use warnings; use Sys::Syslog; while (1) { syslog 'INFO', "$0 ($$): %s", scalar localtime; sleep 1; } ---------- daemonified ---------- Test it like this: ---------- snip ---------- nijushiho:/tmp/try$ ls daemonified* daemonify* nijushiho:/tmp/try$ nijushiho:/tmp/try$ ssh localhost "cd /tmp/try && ./daemonify $PWD/daemonified" nijushiho:/tmp/try$ tail -3 /var/log/messages May 17 00:18:01 nijushiho /tmp/try/daemonified (14462): Fri May 17 00:18:01 2002 May 17 00:18:02 nijushiho /tmp/try/daemonified (14462): Fri May 17 00:18:02 2002 May 17 00:18:03 nijushiho /tmp/try/daemonified (14462): Fri May 17 00:18:03 2002 nijushiho:/tmp/try$ ps -aef | egrep 'PID|daemonified' UID PID PPID C STIME TTY TIME CMD mlamertz 14462 1 1 00:19 ? 00:00:00 /usr/bin/perl /tmp/try/daemonified mlamertz 14483 13904 0 00:19 pts/2 00:00:00 grep daemonified nijushiho:/tmp/try$ kill 14462 nijushiho:/tmp/try$ !ps ps -aef | egrep 'PID|daemonified' UID PID PPID C STIME TTY TIME CMD mlamertz 14510 13904 0 00:20 pts/2 00:00:00 egrep PID|daemonified nijushiho:/tmp/try$ ---------- snip ---------- As you see, the process was running and logging to syslog although the ssh immediately returned. The 'ps' told us that our PPID was 1 which is 'init'. That should be it, but I may have forgotten something since it's been a while that I needed that stuff frequently. To learn more about this kind of stuff, go and buy the late Richard Stevens "Advanced Programming in the Unix(R) Environment". -- If we fail, we will lose the war. Michael Lamertz | +49 221 445420 / +49 171 6900 310 Nordstr. 49 | [EMAIL PROTECTED] 50733 Cologne | http://www.lamertz.net Germany | http://www.perl-ronin.de -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]