How to check if a process id (PID) exists
Solution 1
To check for the existence of a process, use
kill -0 $pid
But just as @unwind said, if you want it to terminate in any case, then just
kill $pid
Otherwise you will have a race condition, where the process might have disappeared after the first kill -0
.
If you want to ignore the text output of kill
and do something based on the exit code, you can
if ! kill $pid > /dev/null 2>&1; then
echo "Could not send SIGTERM to process $pid" >&2
fi
Solution 2
The best way is:
if ps -p $PID > /dev/null
then
echo "$PID is running"
# Do something knowing the pid exists, i.e. the process with $PID is running
fi
The problem with kill -0 $PID
is that the exit code will be non-zero even if the process is running and you don't have permission to kill it. For example:
kill -0 $known_running_pid
and
kill -0 $non_running_pid
have a non-zero exit codes that are indistinguishable for a normal user, but one of them is by assumption running, while the other is not.
Partly related, additional info provided by AnrDaemon: The init process (PID 1) is certainly running on all Linux machines, but not all POSIX systems are Linux. PID 1 is not guaranteed to exist there:
kill -0 1
-bash: kill: (1) - No such process …
DISCUSSION
The answers discussing kill and race conditions are exactly right if the body of the test is a "kill". I came looking for the general "how do you test for a PID existence in bash".
The /proc
method is interesting, but in some sense breaks the spirit of the ps
command abstraction, i.e. you don't need to go looking in /proc
because what if Linus decides to call the exe
file something else?
Solution 3
On systems that implement procfs interface such as Linux, you can just check if /proc/$PID
exists:
if test -d /proc/"$PID"/; then
echo "process exists"
fi
otherwise you can use ps
program:
if [ -n "$(ps -p $PID -o pid=)" ]
In the latter form, -o pid=
is an output format to display only the process ID column with no header. The quotes are necessary for non-empty string operator -n
to give valid result.
Solution 4
ps
command with -p $PID
can do this:
$ ps -p 3531
PID TTY TIME CMD
3531 ? 00:03:07 emacs
Solution 5
You have two ways:
Lets start by looking for a specific application in my laptop:
[root@pinky:~]# ps fax | grep mozilla
3358 ? S 0:00 \_ /bin/sh /usr/lib/firefox-3.5/run-mozilla.sh /usr/lib/firefox-3.5/firefox
16198 pts/2 S+ 0:00 \_ grep mozilla
All examples now will look for PID 3358
.
First way: Run ps aux
and grep
for the PID in the second column. In this example I look for firefox
, and then for it's PID:
[root@pinky:~]# ps aux | awk '{print $2 }' | grep 3358
3358
So your code will be:
if [ ps aux | awk '{print $2 }' | grep -q $PID 2> /dev/null ]; then
kill $PID
fi
Second way: Just look for something in the /proc/$PID
directory. I am using exe
in this example, but you can use anything else.
[root@pinky:~]# ls -l /proc/3358/exe
lrwxrwxrwx. 1 elcuco elcuco 0 2010-06-15 12:33 /proc/3358/exe -> /bin/bash
So your code will be:
if [ -f /proc/$PID/exe ]; then
kill $PID
fi
BTW: whats wrong with kill -9 $PID || true
?
EDIT:
After thinking about it for a few months.. (about 24...) the original idea I gave here is a nice hack, but highly unportable. While it teaches a few implementation details of Linux, it will fail to work on Mac, Solaris or *BSD. It may even fail on future Linux kernels. Please - use "ps" as described in other responses.
Related videos on Youtube
Richard H
Updated on February 16, 2022Comments
-
Richard H about 2 years
In a bash script, I want to do the following (in pseudo-code):
if [ a process exists with $PID ]; then kill $PID fi
What's the appropriate expression for the conditional statement?
-
Alberto Salvia Novella about 3 years
-
Alberto Salvia Novella about 3 yearsBy name: askubuntu.com/questions/157779/…
-
-
just somebody almost 14 years+1 unfortunately kill(1)'s exit code doesn't distinguish the different error situations (looks like it increments the exit value by one for each process it failed to signal). if the OP doesn't mind writing their own kill(2) wrapper, he could have it exit with different values based on the value of ERRNO after a failed kill(2) call.
-
Richard H almost 14 yearsat the moment I am just doing kill -9 with no check - i just get an error "process doesn't exist" if it doesn't exist which isn't very tidy. How would I test what happened?
-
Richard H almost 14 yearslooking at the man page, kill -0 is: "exit code indicates if a signal may be sent". So does this actualy kill a process, or just tell you if it can be killed?
-
Christoffer Hammarström almost 14 years
kill
is somewhat misnamed in that it doesn't necessarily kill the process. It just sends the process a signal.kill $PID
is equivalent tokill -15 $PID
, which sends signal 15, SIGTERM to the process, which is an instruction to terminate. There isn't a signal 0, that's a special value tellingkill
to just check if a signal could be sent to the process, which is for most purposes more or less equivalent to checking if it exists. See linux.die.net/man/2/kill and linux.die.net/man/7/signal -
Christoffer Hammarström almost 14 yearsDon't carelessly
kill -9
. That just instantly kills the process giving it no chance to clean up after itself. Instead usekill
which is equivalent tokill -15
. If that doesn't work, you should find out why, and only as a last resort usekill -9
. -
mckoss about 12 yearsThis has the problem that if the process is not owned by the running user, you may not have permissions to call kill -0. Better to use ps -p $PID > /dev/null 2>&1, which allows you to see process status, even if you do not have permissions to send a signal.
-
Christoffer Hammarström about 12 years@mckoss: In that case he can't kill it anyway.
-
sdaau almost 11 yearsSo, I guess - to use
kill -0
, I, in fact, have to do this:kill -0 25667 ; echo $?
- and then if I get a0
returned, then the process with that PID can be killed; and if the process PID (say) doesn't exist, the$?
will be1
, indicating a failure. Is that correct? -
Christoffer Hammarström almost 11 years@sdaau: Read again. If you're going to kill it anyway, then just kill it, otherwise you will have a race condition. But yes, an exit code of 0 means that it was possible to send a signal to it at that time. It does not mean that you can be sure that you can send a signal to it a millisecond later.
-
Mihnea Simian over 10 yearsIf for some reason $PID is 0 (e.g. it was supposed to be read from a pid file, but file is missing and some logic decides to place a "0" instead), then kill -0 0 returns error code 0, as if process pid exists! Beware of this pitfall.
-
IttayD about 10 yearsps -p always returns status of 0 for me
-
nurettin about 10 yearsat least the kill -9 part seems wrong (doesn't kill subprocesses)
-
Will about 9 yearsThe second method works on Mac too, as an added plus (Mac OS X has no /proc FS). You can, however, avoid using a subshell and use this on both Mac and Linux:
if ps -p"$PID" -o "pid=" >/dev/null 2>&1; then echo "Process is running..."; fi
-
tenmiles almost 9 yearsWhy do I get [: missing `]' when using the first way?
-
Ligemer about 8 yearsps -p #### worked fine for me under Ubuntu 14.04, +1 thanks!
-
Douglas Correa about 8 yearsps -p always returns status code 0 in os x because it prints an empty list of process when it not matches any running process
-
tripleee over 7 yearsUnfortunately,
ps
options and features tend to vary between platforms, so it's still not entirely portable. -
tripleee over 7 years
pidof
does not return a negative number, as a negative PID does not make any sense, and you can't killinit
, so your conditional makes no sense (and besides, you'd need to escape the>
to prevent it from performing a redirection). You want to check for an empty result, but of course, like any decent tool,pidof
sets an exit code to tell you whether it worked, so the proper solution isif Pid=$(pidof 'process_name'); then ...
or (if you won't need the value inPid
later on) simplyif pidof 'process_name'; then...
-
user137369 about 7 yearsI can confirm that on macOS Sierra, this works. Also, the
-p
is unnecessary, at least in that case.ps $PID
has the exact same result. -
David Roundy over 6 yearsPortability is a good reason to avoid using /proc, but linux breaking its ABI is not a scenario I would particularly worry about.
-
Magne about 6 yearsif
$PID
is empty then[ -e /proc/$PID ]
will still return true, since the/proc/
directory still exists. -
Bruno Bronosky about 6 years@tripleee is right the
pidof
example is full of misunderstandings about how bashtest
works. gnu.org/software/bash/manual/html_node/… -
Alexander Yancharuk over 5 years
/proc/$PID/exe
is not a regular file. So,[ -f /proc/$PID/exe ]
will always returns afalse
result. Try[ -h /proc/$PID/exe ]
. -
Calumah over 5 yearswait is not so effective as process should be child of current shell or it will give :
pid 123 is not a child of this shell
-
antichris over 4 yearsThis does not work on BusyBox. OpenWrt only recognizes
w
for "wide output", Alpine takes only-o
for filtering output columns. Docs also mention a-T
for showing threads. There is no-p
parameter. -
Mikko Rantalainen over 3 yearsIf you want to know if the process with id $PID exists, you can just do
test -d /proc/$PID
instead of starting additional processes. Note that you cannot ever know if a process exists in some another PID namespace. -
Mikko Rantalainen over 3 yearsActually, test is often shell builtin and only executes syscalls by the shell itself.
-
Christoffer Hammarström almost 3 yearsIf $PID is 0, then the signal is sent to every process in the process group of the calling process.
-
Cadoiz over 2 yearsJust for other noobs like I seem to be:
> /dev/null
does not read> 0
(comparison), but forwards the output to nothingness. I just proposed an update to your brilliant and +1ed answer and incorporated the comment by AnrDaemon. Alternatively tops -p $PID > /dev/null
, you can internally check (without a new process) whether aPID
is running with[[ ! -z ${PID+x} ]]
, as statet e.g. here. -
Maxim Egorushkin over 2 years
-e /proc/$PID/status
makes-n "$PID"
check unnecessary, because there is no/proc//status
file. -
Richard Tyler Miles over 2 years
ps -p
seems to be the correct solution for RHEL -
Tobias Hochgürtel almost 2 yearswhy did this answer received down votes?
-
Gabriel Staples almost 2 years@TobiasHochgürtel, I don't know. It was probably because my answer has a portion that looks very similar to the main answer, and goes against the advice of
shellcheck
in some ways. Unfortunately, however, many questions get immediately downvoted by people who are watching the question feed. It is incredibly difficult for anyone, myself included, to ask a question without immediately getting downvotes, even to this day. That being said, I just rewrote my answer and find it to be much better now.