How to check if a process id (PID) exists

BashProcessPid

Bash Problem Overview


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?

Bash Solutions


Solution 1 - Bash

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 2 - Bash

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 3 - Bash

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 - Bash

ps command with -p $PID can do this:

$ ps -p 3531
  PID TTY          TIME CMD
 3531 ?        00:03:07 emacs

Solution 5 - Bash

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.

Solution 6 - Bash

It seems like you want

wait $PID

which will return when $pid finishes.

Otherwise you can use

ps -p $PID

to check if the process is still alive (this is more effective than kill -0 $pid because it will work even if you don't own the pid).

Solution 7 - Bash

I think that is a bad solution, that opens up for race conditions. What if the process dies between your test and your call to kill? Then kill will fail. So why not just try the kill in all cases, and check its return value to find out how it went?

Solution 8 - Bash

For example in GNU/Linux you can use:

Pid=$(pidof `process_name`)

if [ $Pid > 0 ]; then

   do something
else

   do something
fi 

Or something like

Pin=$(ps -A | grep name | awk 'print $4}')
echo $PIN

and that shows you the name of the app, just the name without ID.

Solution 9 - Bash

By pid:

pgrep [pid] >/dev/null

By name:

pgrep -u [user] -x [name] >/dev/null

"-x" means "exact match".

Solution 10 - Bash

here i store the PID in a file called .pid (which is kind of like /run/...) and only execute the script if not already being executed.

#!/bin/bash
if [ -f .pid ]; then
  read pid < .pid
  echo $pid
  ps -p $pid > /dev/null
  r=$?
  if [ $r -eq 0 ]; then
    echo "$pid is currently running, not executing $0 twice, exiting now..."
    exit 1
  fi
fi

echo $$ > .pid

# do things here

rm .pid

note: there is a race condition as it does not check how that pid is called. if the system is rebooted and .pid exists but is used by a different application this might lead 'unforeseen consequences'.

Solution 11 - Bash

I learned from and upvoted @FDS's answer here, because it is good and correct. But, here's a form I find easier to read and understand:

pid=1234
ps --pid "$pid" > /dev/null
if [ "$?" -eq 0 ]; then
    echo "PID $pid exists and is running."
fi

Update: shellcheck check_if_pid_exists.sh tells me I should actually do it the other way (as @FDS shows) to avoid redundancy:

pid=1234
if ps --pid "$pid" > /dev/null; then
    echo "PID $pid exists and is running."
fi

So...maybe I'll adjust to doing it that way in the future.

Anyway, here is a full, runnable program (I guess that's my contribution here ):

check_if_pid_exists.sh:

#!/usr/bin/env bash

pid=1234

if [ "$#" -gt 0 ]; then
    # At least 1 argument was passed in, so assume it is the PID
    pid="$1"
fi

# Try to print the process (`ps`) information for this PID. Send it to
# /dev/null, however, so we don't actually have to look at it. We just want
# the return code, `$?`, which will be 0 if the process exists and some other
# number if not.
ps --pid "$pid" > /dev/null
if [ "$?" -eq 0 ]; then
    echo "PID $pid exists and is running."
else
    echo "PID $pid does NOT exist."
fi

Sample run calls and output:

eRCaGuy_hello_world/bash$ ./check_if_pid_exists.sh 28876
PID 28876 exists and is running.

eRCaGuy_hello_world/bash$ ./check_if_pid_exists.sh
PID 1234 does NOT exist.

eRCaGuy_hello_world/bash$ ./check_if_pid_exists.sh 5678
PID 5678 does NOT exist.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRichard HView Question on Stackoverflow
Solution 1 - BashFDSView Answer on Stackoverflow
Solution 2 - BashChristoffer HammarströmView Answer on Stackoverflow
Solution 3 - Bashuser2683246View Answer on Stackoverflow
Solution 4 - BashoherralaView Answer on Stackoverflow
Solution 5 - BashelcucoView Answer on Stackoverflow
Solution 6 - BashGagan GamiView Answer on Stackoverflow
Solution 7 - BashunwindView Answer on Stackoverflow
Solution 8 - BashinukazeView Answer on Stackoverflow
Solution 9 - BashAlberto Salvia NovellaView Answer on Stackoverflow
Solution 10 - BashinvalidmagicView Answer on Stackoverflow
Solution 11 - BashGabriel StaplesView Answer on Stackoverflow