Re: how to make a demon in perl?
by Dog and Pony (Priest) on Oct 01, 2002 at 08:18 UTC
|
Personally, I use the way described here more or less, and just add the script to the startup (remember to make it executable). The main program then exists while the forked copy continues as a daemon.
Otherwise, it should be enough to just add the script to your startup with a '&' afterwards to put it in the background, no need to have any shell script in between (as long as you have a correct shebang line, that is the #!/usr/bin/perl one in the start of your script. I think. :)
You have moved into a dark place.
It is pitch black. You are likely to be eaten by a grue. | [reply] [d/l] |
|
| [reply] |
|
COOL
that is a very simple yet much better than what I was about to do, thx.
by the way, how do I edit my questions ? (i'd like to change the title)
| [reply] |
|
| [reply] |
Re: how to make a demon in perl?
by robartes (Priest) on Oct 01, 2002 at 09:12 UTC
|
Hi Sihal,
generally, you should take the following steps to daemonize a program:
* Fork your program. The parent exits and the child continues with the following steps.
* Close or reassign STDOUT, STDIN and STDERR (to avoid scribbling all over the terminal the process was started from). You can outright close the file descriptors or redirect them to /dev/null or something.
* Dissociate from your terminal to avoid dying when the original shell you started from exits.
A specific example that implements the above three things is linked from Dog and Pony's post above.
Once you have a properly daemonizing script, you can put it in the /etc/rc.d hierarchy to have it started automatically at system boot time (if you have a System V startup sequence, that is :) ).
CU Robartes- | [reply] |
|
thank you again for making it that clear :-)
I now have enough info to get me started, but feel free to ad remarks that could prove interesting :-)
| [reply] |
Re: you to make a demon in perl
by fsn (Friar) on Oct 01, 2002 at 08:38 UTC
|
Just creating a script in /etc/rc.d/ somewhere is not enough. The runlevel startup script that calls the individual startup scripts, calls them in the foreground. So, if the startup script does not fork and exit, the bootprocess will hang forever.
Having the script fork itself, is one solution. Creating a startup script that calls your script in the background, with an '&', is another. There are probably a lot of simple startup scripts in your /etc/rc.d/* already, check them out. One note though: Linux, and RedHat in particular, uses a shell function 'daemon' instead of running the binary directly with an '&'. | [reply] |
|
Nice I must admit that I wasn't aware of the risk of making the bootprocess hang... thanx all for your comments
| [reply] |
Re: how to make a demon in perl?
by RMGir (Prior) on Oct 01, 2002 at 12:38 UTC
|
There is one important point that wasn't raised by the other posts, or by the FAQ entry linked above.
Your program should "chdir '/'" or the equivalent if at all possible, so you don't keep a working directory on a mounted device.
If the device has to be unmounted for maintenance, it would be "busy" and locked if your process still has its current working directory there.
That's not usually a problem for non-daemon processes, since the sysadmin can boot off all interactive users without taking the system down. But if you're "half-daemonized", they'll either have to track down which process has the directory in use, or reboot the box.
If you're going to be logging to a file, chdir to that directory; that way, only one filesystem is locked down.
--
Mike | [reply] |
|
what is the difference between chdir to the "/" directory or to /var/log/ for ex? which one is the safest ?
I had a look at the daemonize module; looks pretty neat.
| [reply] |
|
Type "mount" at your command line. You'll see a listing something like this:
$ mount
/dev/sda1 on / type ext3 (rw)
none on /proc type proc (rw)
/dev/sda7 on /data type ext3 (rw)
none on /dev/pts type devpts (rw,gid=5,mode=620)
none on /dev/shm type tmpfs (rw)
/dev/sda5 on /tmp type ext3 (rw)
/dev/sda3 on /usr type ext3 (rw)
/dev/sda2 on /var type ext3 (rw)
nfsserver:/vol/office/home on /home type nfs (rw,addr=nfsserver)
nfsserver:/vol/office/log on /log type nfs (rw,addr=nfsserver)
Each of the /dev/sd\d items is a different disk on your system, and the "type nfs" entries are remote volumes you're connected to.
The system can't operate without / being mounted, so it doesn't make a difference if that's your current working directory. If / is dead, the system definitely needs a reboot anyways, at least.
/var/log (well, /var at least) is usually a separate device, which the system could theoretically live without.
In fact, if your daemon logs via syslog, as such things probably should, the admin can unmount /var/log even if lots of daemons normally log there by reconfiguring syslogd to log somewhere else.
But, in general, /var/xxx is probably an ok 3rd choice, with / being best, and /tmp probably being 2nd.
--
Mike | [reply] [d/l] |
|
|
If you have a log file you're writing to in /var/log, then chdir to /var/log - you're already going to keep /var/log busy, might as well not keep / busy too. If you're not logging directly, (perhpas you're using syslog, like a good daemon), then chdir to /.
-- Dan
| [reply] |
Re: how to make a demon in perl?
by blm (Hermit) on Oct 01, 2002 at 12:03 UTC
|
You don't need to make a daemon for the most part you can use nohup (see man 1 nohup). nohup protects your process from getting the signal HUP when you disconnect your terminal (eg close your ssh client). This will allow your perl script should keep running. My Debian box's nohup appends output of the script to nohup.out. So if your script spews information out, watch the size of nohup.out files.
If you still want to create a daemon here is some code I stumbled on and saved for a rainy day. I honestly can't remember the source site on the web. (If you know it and I should put it here let me know!)
use POSIX qw(setsid);
chdir '/' or die "Can't chdir to /: $!";
umask 0;
open STDIN, '/dev/null' or die "Can't read /dev/null: $!";
#open STDOUT, '>/dev/null' or die "Can't write to /dev/null: $!";
open STDERR, '>/dev/null' or die "Can't write to /dev/null: $!";
defined(my $pid = fork) or die "Can't fork: $!";
exit if $pid; #parent dies
#Here is the daemon part
setsid or die "Can't start a new session: $!";
while(1) {
sleep(5);
print "Hello...\n";
}
--blm--
Please note: You use my code at your risk. There are no garantees implied or otherwise. | [reply] [d/l] [select] |
|
I'd modify this code to fork first, then close all the filehandles - especially STDERR: what's the point of calling "die" if your STDERR is closed?
-- Dan
| [reply] |
|
Silly me! Yes, calling die when STDERR is redirected to /dev/null seems pointless except to stop the script. For this exit would suffice.
That said, I believe it is done before the fork is perform because the child inherits the file descriptors like STDIN and STDOUT.(1)
Nevertheless, I made the modifications you suggest and the daemon is still detached from the terminal such that it keeps running when I disconnect my terminal. Maybe someone can explain to me what is happening here?
--blm--
| [reply] |
|
|
|
|
this is pretty much the same as what was posted above i guess... but i didn't know nohup, i'll have a look at how it works
| [reply] |
Re: how to make a demon in perl?
by zentara (Cardinal) on Oct 01, 2002 at 15:53 UTC
|
Hi, here's one which is slightly simpler, but similar to Dog&Pony's link.
#!/usr/bin/perl
use strict;
use POSIX;
# run in background?
# 1 = yes, 0 = no
my $daemon = 1;
#change namelisting in ps,
# but killall still requires real name
#$0 = 'daemonz';
if($daemon) {
exit if fork;
POSIX::setsid();
}
# script goes here
while(1){sleep(1)}
| [reply] [d/l] |
According to Network Programming with Perl...
by Argel (Prior) on Oct 01, 2002 at 22:35 UTC
|
According to Addison Wesley's "Network Programming with Perl" book your program should do the following:
- Put itself into the background
- Close STDIN, STDOUT, and STDERR
- Completely dissacociate from the controlling terminal
- Change the current working directory to /
- Change the file creation mask to a known state
- Normalize the PATH environment variable
- Write the process IDs to a file in /var/run or a similar location
You can learn more about the book here.
For anyone wanting to download the example source code you want Chapter 10 (for anyone reading the book, it starts on page 312). Looks like the author (Lincoln D. Stein, the author of CGI.pm) uses the POSIX module mentioned above.
-- Argel | [reply] |
Re: how to make a demon in perl?
by Mr. Muskrat (Canon) on Oct 01, 2002 at 14:30 UTC
|
how to make a demon in perl
You can't. We don't need any more any way. There are way too many fallen angels as it is!
;)
| [reply] |
|
alright i meant daemon
but my daemons while behave as demons i suspect so.....
| [reply] |
|
| [reply] |