How should I check whether a given PID is running?
The perl function kill(0,$pid)
can be used.
If the return code is 1 then the PID exists and you're allowed to send a signal to it.
If the return code is 0 then you need to check $!. It may be EPERM (permission denied) which means the process exists or ESRCH in which case the process doesn't exist.
If your checking code is running as root
then you can simplify this to just checking the return code of kill; 0=>error, 1=>ok
For example:
% perl -d -e 0
Loading DB routines from perl5db.pl version 1.37
Editor support available.
Enter h or 'h h' for help, or 'man perldebug' for more help.
main::(-e:1): 0
DB<1> print kill(0,500)
0
DB<2> print $!
No such process
DB<3> print kill(0,1)
0
DB<4> print $!
Operation not permitted
DB<5> print kill(0,$$)
1
This can be made into a simple function
use Errno;
sub test_pid($)
{
my ($pid)=@_;
my $not_present=(!kill(0,$pid) && $! == Errno::ESRCH);
return($not_present);
}
print "PID 500 not present\n" if test_pid(500);
print "PID 1 not present\n" if test_pid(1);
print "PID $$ not present\n" if test_pid($$);
- I’m 99.9% sure that checking whether
/proc/PID
exists (and is a directory) is 98% as reliable as thekill 0
technique. The reason why the 98% isn’t 100% is a point that Stephen Harris touched on (and bounced off) in a comment — namely, the/proc
filesystem might not be mounted. It may be valid to claim that a Linux system without/proc
is a damaged, degraded system — after all, things likeps
,top
, andlsof
probably won’t work — and so this might not be an issue for a production system. But it is (theoretically) possible for it never to have been mounted (although this might prevent the system from coming up to a normal state), it is definitely possible for it to be unmounted (I’ve tested it1), and I believe that there isn’t any guarantee that it will exist (i.e., it’s not required by POSIX). And, unless the system is completely hosed,kill
will work. - Stephen’s comment talks about “going out to the filesystem”
and “using native system calls”.
I believe that this is largely a red herring.
- Yes, any attempt to access
/proc
requires reading the root directory to find the/proc
filesystem. This is true for any attempt to access any file by an absolute pathname, including things in/bin
,/etc
, and/dev
. This happens so often that the root directory is surely cached in memory for the entire lifetime (uptime) of the system, so this step can be done without any disk I/O. And, once you have the inode of/proc
, everything else that happens is in memory. - How do you access
/proc
? Withstat
,open
,readdir
, etc., which are native system calls every bit as much askill
.
- Yes, any attempt to access
The question talks about a process running. This is a slippery phrase. If you actually want to test whether the process is running (i.e., in the run queue; maybe the current process on some CPU; not sleeping, waiting, or stopped), you may need to do a
ps PID
and read the output, or look at/proc/PID/stat
. But I see no hint in your question or comments that you are concerned with this.The elephant in the room, however, is that a zombie2 process can be difficult to distinguish from a process that is alive and well.
kill 0
works on a zombie, and/proc/PID
exists. You can identify zombies with the techniques listed in the previous paragraph (doingps PID
and reading the output, or looking at/proc/PID/stat
). My very quick & casual (i.e., not very thorough) testing suggests that you can also do this by doing areadlink
orlstat
on/proc/PID/cwd
,/proc/PID/root
, or/proc/PID/exe
— these will fail on zombies. (However, they will also fail on processes you don’t own.)
____________
1 if the -f
(force) option doesn’t work,
try -l
(lazy).
2 i.e., a process that has exited/died/terminated,
but whose parent has not yet done a wait
.