1

According to the ps man page:

Except as described below, process selection options are additive. The default selection is discarded, and then the selected processes are added to the set of processes to be displayed. A process will thus be shown if it meets any of the given selection criteria.

I take this to mean that the matches are "OR"ed, not "AND"ed.

I am developing my own locking script which creates a directory (mkdir mutex) and writes PPID and PID information to a file in this dir. One of the functions in the script is to clean up stale lock files by looping through all lock files, and extracting $PPID and $PID. It next determines if a process which has PID $PID and PPID $PPID is still running.

However with ps I am getting all processes which have PPID $PPID, and I'm also getting PID $PID. I want it to show me only the process with pid $PID and ppid $PPID

I understand grep is intuitively useful here, but is there a "less expensive" method to use? Perhaps another process-related utility?


procps-3.2.7-16.el5

2
  • ps -p $PID will show the process with only the PID $PID. Similar to this, you want a command that meets the $PPID condition too along with $PID, am I right?
    – Sreeraj
    Commented Nov 25, 2014 at 4:05
  • Yes that's correct. Must match pid $PID as well as its parent pid of $PPID. Both conditions. Matched pair, etc. etc. Commented Nov 25, 2014 at 7:00

3 Answers 3

0

I just checked, it seems CentOS 6.6 pgrep doesn't have the -F option, so this isn't applicable. I'll leave this answer here since it might be useful in other cases.


pgrep might be what you want:

-P, --parent ppid,...
      Only match processes whose parent process ID is listed.
-F, --pidfile file
      Read  PID's  from  file.  This option is perhaps more useful for
      pkill than pgrep.

It seems that pgrep with -F will filter the PIDs to match those in the file:

$ pgrep libvirtd
1343
18471
$ pgrep -F /var/run/libvirtd.pid -P 1
1343
$ echo -n 18471 > other-libvirtd.pid
$ pgrep -F other-libvirtd.pid -P 1
$ pgrep -F other-libvirtd.pid
18471
0

Using one ps option and further filtering with grep or awk is a reasonable approach.

Do pass the -o option to ps and limit the fields to the ones you need. Use an equal sign after each field name to suppress the header line. If you don't need the command name, don't include comm or args, which could include newlines (and in any security-sensitive context, if they contain a newline, make sure your script does something sensible). For example, if you only need the PID and want all processes that belong to a certain group and are running on a certain TTY, then you can collect the PIDs with

pid_list=$(ps -t tty3 -o 'pid= gid=' | awk '$2 == 1234 || $2 == "somegroup"')

In your case, this is overkill. There is a single process that has a given PID, so the condition -p $PID is all the filtering you need. Retrieve the PPID of the process by that PID, and compare it with the expected value. ps will output nothing if there is no process with that PID.

read pid expected_ppid <"$pidfile"
actual_ppid=$(ps -o ppid= -p "$pid")
if [ "$actual_ppid" = "$expected_ppid" ]; then …

Keep in mind that if you find a process with the right characteristics, it could be the same process, or it could be an unrelated process because the process you expect is long dead and its PID has been reused.

4
  • An unrelated process could have the exact PID and PPID, but what are the chances? And secondly, what is a better approach? Commented Nov 25, 2014 at 23:10
  • 1
    @FelipeAlvarez The chances are low, but over time the probability that you will be woken up at 3am because the company's most important web server was killed by a routine cleanup script due to a freak PID coincidence increases to 1. A supervisor program (i.e. the parent does the management) is the Right Way; I'm sure the authors of daemontools, upstart, systemd and others have published rants on that topic. Another correct way on Linux is with containers. Commented Nov 25, 2014 at 23:14
  • Link for more information on so-called containers? Commented Nov 30, 2014 at 2:54
  • @FelipeAlvarez en.wikipedia.org/wiki/Cgroups en.wikipedia.org/wiki/LXC I don't have any particular tutorial to recommend but there are plenty out there. Commented Nov 30, 2014 at 12:47
0

This is a Shell solution that won't require external utilities other than ps

if [[ `ps --pid $PID -oppid=` = $PPID ]]
then
   : still running
else
   : not running
fi

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .