15

I have a .pid file, and I need to check if the process is running. So far I found two options

kill -0 `cat something.pid`

which prints out an error if the pid isn't running. I know this can be redirected to /dev/null, but it makes me think that this isn't the best solution.

The second solution would be to use ps, which however also prints on the STDOUT

ps -ef `cat something.pid`

Is it normal to redirect the output to /dev/null and just use the status code returned, or is it a sign that I'm doing something wrong and I need a different command?

Jakub Arnold
  • 1,674
  • 10
  • 25
  • 33

6 Answers6

11

for most linux distros enumerating the /proc/{pid} is a good way to obtain information about the running processes, and usually how the userspace commands like "ps" are communicating with the kernel. So for example you can do;

[ -d "/proc/${kpid}" ] && echo "process exists" || echo "process not exists"

Edit: you should check that kpid is set, but this is more useful as it will return "not exists" for unset ${kpid}

[ -n "${kpid}" -a -d "/proc/${kpid}" ] && echo "process exists" || echo "process not exists"
Tom
  • 10,886
  • 5
  • 39
  • 62
  • @SteveMuster This would make the answer Linux-specific. There is no /proc on OSX. And I think there's no /proc on BSD. – ash Nov 26 '14 at 15:44
  • Note with this you need to make sure `${kpid}` exists – Wilf Aug 15 '15 at 12:55
  • @Wilf I edited it, so it returns "process not exists" for unset ${kpid} – Tom Aug 15 '15 at 17:18
  • Thanks - I was doing a script that checks a PID using a similar method and it didn't work till I found this was the issue :) – Wilf Aug 15 '15 at 20:27
8

As Anders noted, you should use kill -0 for POSIX compliance.

On Linux systems, you can also check for the existence of a file in the /proc filesystem, e.g.,

-f /proc/$(cat something.pid)/status
cjc
  • 24,533
  • 2
  • 49
  • 69
4

If this is in a script (which I assume is the case as you're worried about printing to stdout) then the following would be how you could do it:

if ps -p $(cat something.pid) > /dev/null 2>&1
then
    kill $(cat something.pid)
else
    # Deal with the fact that the process isn't running
    # i.e. clear up the pid file
fi

The ps -p looks for a process with the pid specified in something.pid (the $() syntax is a slightly newer version of the backtick. Backtick needs escaping in certain circumstances which the new form doesn't). The 2>&1 redirects stderr for that command as well.

If the ps -p command doesn't find the process with that PID it exits with a error > 0 and so the else gets executed. Otherwise the kill statement. You can negate the above if you want by doing:

if ! ps -p ...

Hope that answers your question. Obviously be careful and test a lot when using dangerous commands such as kill.

webtoe
  • 1,946
  • 11
  • 12
1

Here are some options:

  • If you're writing init-script (e.g. the one to place in /etc/init.d/) and if you're using Debian-based distro, you'd better use start-stop-daemon:
    # start-stop-daemon -T -p $PIDFILE -u $USER_NAME -n $NAME
    You should get exit code 0 if it's running.
  • You may use pgrep and pkill from procps package:
    pgrep --pidfile $PIDFILE
jollyroger
  • 1,650
  • 11
  • 19
1

If you have pid file you may use pgrep to check whether process is running:

    if pgrep -F something.pid; then
        echo "Running"
    else
        echo "Not running"
    fi

On linux you may also check for existence of /proc/$pid file:

    if [ -d "/proc/${pid}" ]; then
        echo "Running";
    else
        echo "Not running";
    fi
Dima L.
  • 121
  • 6
-1

if you are using java on linux

long pid = readPIDFile(); // write this yourself
boolean running = new File(String.format("/proc/%d", pid)).exists();