Reputation: 4836
I have a simple Perl script that simply prints a line of text to stdout. What I want to accomplish is that while this script runs, if I (or someone else) issues a signal to that process to stop, I want it to trap that signal and exit cleanly. The code I have looks like the following
#!/usr/bin/perl -w
$| = 1;
use sigtrap 'handler' => \&sigtrap, 'HUP', 'INT','ABRT','QUIT','TERM';
while(1){
print "Working...\n";
sleep(2);
}
sub sigtrap(){
print "Caught a signal\n";
exit(1);
}
While this works well when I actually hit ctrl-c from the command line, if I issue a
kill -9 <pid>
It just dies. How do I get it to execute something before exiting? My general idea is to use this framework to capture when this script dies on a server due to a server reboot for maintenance or failure.
Thanks much in advance
Upvotes: 6
Views: 5395
Reputation: 19266
You're sending two very different signals to your process. Pressing Ctrl-C
in console usually sends the process a TERM
INT
signal, which - judging by your code - is caught and serviced. kill -9
, though, sends signal number 9 explicitly, which is called KILL
. This is one of the signals whose servicing cannot be redefined and delivery of this signal always immediately ends the process, which is done by the kernel itself.
Upvotes: 4
Reputation: 8696
Signal #9 (SIGKILL) can not be trapped. That's how Unix is designed.
But the system does not send that signal when shutting down for maintainance. At least if your daemon behaves correctly. It will normally send the TERM signal (or more exactly what your daemon handling script in /etc/init.d
does). Only processes that do not correctly shutdown after a timeout will receive SIGKILL.
So your aim should be to correctly handle the TERM signal and to write the wrapper script in /etc/init.d
that will be called when the system is changing runlevel.
Update: You can use the Daemon::Control module for the init script.
Upvotes: 11
Reputation: 28713
As far as I know you can't capture kill -9
. Try kill <pid>
instead.
Upvotes: 3