kill#
Send a signal to a list of processes.
kill is Perl’s front-end to the kill(2) system call. It delivers
SIGNAL to each process identified by LIST and returns the number
of arguments that were successfully signalled. It is also the standard
way to ask the kernel “does this PID still exist and may I signal it?”
without actually disturbing the target, via the signal-zero form.
Synopsis#
kill SIGNAL, LIST
kill SIGNAL # tainting side-effect only; returns 0
What you get back#
The number of arguments in LIST that were successfully passed to
kill(2). This is not necessarily the number of processes that
actually received the signal — when SIGNAL is negative, or when a
PID identifies a process group, one argument can target many
processes. On permission or “no such process” errors for an argument,
that argument is not counted and $! is set to the
corresponding errno (EPERM, ESRCH, EINVAL).
my $cnt = kill 'HUP', $child1, $child2;
kill 'KILL', @goners;
With an empty LIST, no signal is sent and the return value is 0.
The bare kill SIGNAL form is sometimes written purely to trigger
taint checks on SIGNAL; see perlsec.
SIGNAL: name or number#
SIGNAL may be either a signal name (a string) or a signal number.
The string form is recommended for portability because the same
signal can have different numbers on different operating systems.
A signal name may carry the SIG prefix or not — 'TERM' and
'SIGTERM' name the same signal.
kill 'TERM', $pid; # portable
kill 'SIGTERM', $pid; # also fine
kill 15, $pid; # SIGTERM on Linux; may differ elsewhere
kill 9, $pid; # SIGKILL on Linux
The list of signal names available on the current platform lives in
$Config{sig_name}, provided by the Config
module.
SIGNAL 0: liveness check#
If SIGNAL is the number 0 or the string 'ZERO' (or 'SIGZERO'),
no signal is actually delivered. kill(2) still performs its
permission check, so the call tells you whether it would be
possible to signal the process — that is, the process exists and
is owned by the same user, or the caller is the super-user.
if (kill 0, $pid) {
# process exists and we may signal it
}
elsif ($!{ESRCH}) {
# no such process — it has exited and been reaped
}
elsif ($!{EPERM}) {
# it exists but we are not allowed to signal it
}
This is the canonical idiom for checking that a child is still alive,
even as a zombie, and has not changed its UID. It does not reap
the child — use waitpid for that.
Negative SIGNAL: signal a process group#
A negative signal name or number signals a whole process group
instead of a single process. kill '-KILL', $pgrp and
kill -9, $pgrp both send SIGKILL to every process in the group
identified by $pgrp.
kill '-TERM', $pgrp; # polite shutdown of the whole group
kill -9, $pgrp; # forced
Positive signals are almost always what you want. Reach for a
negative signal only when the target is deliberately a process group
leader (for example a child you placed in its own group with
setpgrp so you can terminate the subtree at once).
PID 0, negative PIDs#
The behaviour of kill when a PID is zero or negative depends on
the operating system. On POSIX-conforming systems (Linux included):
PID
0— signal the sender’s own process group.PID
-1— signal every process the caller has permission to signal (super-user: the whole system, minus a few special PIDs).Any other negative PID — behaves like a negative
SIGNALagainst the absolute value: signal the process group whose PGID equalsabs(PID).
If both SIGNAL and the PID are negative, the result is undefined;
a future Perl may warn. Do not combine the two.
Examples#
Politely ask a child to shut down, then escalate:
kill 'TERM', $child;
sleep 2;
kill 'KILL', $child if kill 0, $child;
waitpid $child, 0;
Reap nothing, just check whether a PID file still names a live process:
open my $fh, "<", "/run/daemon.pid" or die $!;
chomp(my $pid = <$fh>);
close $fh;
if (kill 0, $pid) {
print "daemon alive (pid $pid)\n";
} else {
print "stale pid file: $!\n";
unlink "/run/daemon.pid";
}
Signal a whole process group created by a shell pipeline child:
my $pgrp = getpgrp($child);
kill '-TERM', $pgrp;
Install a handler and send yourself a signal:
local $SIG{USR1} = sub { warn "got USR1\n" };
kill 'USR1', $$; # $$ is our own PID
Broadcast to several workers and find out how many were reachable:
my @workers = (1234, 1235, 9999); # 9999 has exited
my $hit = kill 'HUP', @workers; # probably 2
warn "lost a worker: $!\n" if $hit < @workers;
Edge cases#
Empty LIST:
kill 'TERM'sends nothing and returns0. The call still evaluatesSIGNAL, which is the only reason to write it (taint propagation).Unknown signal name: raises an exception (
Unrecognized signal name "FOO"). Validate against$Config{sig_name}if the name comes from user input.$!after partial success:killwalksLISTleft to right.$!reflects the last failing argument, not all of them. If you need per-PID errors, callkillonce per PID.Zombies still count as alive:
kill 0, $zombie_pidreturns truthy until the child has been reaped withwaitorwaitpid. This is usually what you want for a liveness check; occasionally it surprises.Signal delivery is asynchronous: a successful
killonly means the signal was queued. The handler in%SIGon the receiving process may run later, and Perl’s safe-signal machinery defers delivery to the next opcode boundary.Sending to yourself:
kill SIGNAL, $$works and is the usual way to test your own%SIGhandlers.No LIST, with taint: under
-T, writingkill 'TERM'propagates taintedness of'TERM'for the side-effect of triggering the check — the form has no other use.
Differences from upstream#
Fully compatible with upstream Perl 5.42.
See also#
fork— create the child process you are later going to signalwait— reap any terminated child, clearing zombies thatkill 0would still report as alivewaitpid— reap a specific child, optionally non-blocking (WNOHANG) so it pairs cleanly withkill 0getpgrp/setpgrp— inspect and change process-group membership, which is what negative-SIGNALkilloperates on%SIG— install handlers for the signals you send withkillperlipc— full treatment of signals, handlers, and safe-signal semantics