How to get pids in one process group in Linux OS

18.9k views Asked by At

I have one question on Linux pid things. How to get pids in one same group? It seems easy to get all pids or pgid with 'ps' command in Linux, but how to get the pids that belong to same group, or in other words, how to get the pids of one same program? Anyone please give me some help on this? Thank you!

4

There are 4 answers

2
TafT On

Based on man ps there are four parameters which deal with groups:

-G grplist
      Select by real group ID (RGID) or name.  This selects the processes whose real group name or ID is in the grplist list.  The real group ID identifies the group of the user who created the process, see getgid(2).

-g grplist
      Select by session OR by effective group name.  Selection by session is specified by many standards, but selection by effective group is the logical behavior that several other operating systems use.  This ps will select by session when the list is
      completely numeric (as sessionsare).  Group ID numbers will work only when some group names are also specified.  See the -s and --group options.

--Group grplist
      Select by real group ID (RGID) or name.  Identical to -G.

--group grplist
      Select by effective group ID (EGID) or name.  This selects the processes whose effective group name or ID is in grouplist.  The effective group ID describes the group whose file access permissions are used by the process (see getegid(2)).  The -g
      option is often an alternative to --group.

So you could get the group ID for your program using getpgrp [pid-of-your-program] then call ps -G [group-if-of-your-program].

That might not be what you want though. Process Groups and processes that form a tree seem to be different things. ppid is the parent pid of a process, you might want something that tells you all the pids with a given pid as their ppid? I don't think there is anything to guarantee that is the same as all the pids being in the same process group, in fact if there is only one process group per-process they cannot be.

As suggested above, pstree should help you get an idea of what is going on. The --show-pids option will give you all the pids as well which might be helpful.

0
Edw4rd On

from man ps

To print a process tree:
      ps -ejH
      ps axjf

pstree can also help

Updated: Use pidof to find the process pids of the named programs. e.g. pidof chrome will get all chrome pids.

2
Vi. On

All other answers seem to mention ps, but none tries to access /proc directly.

On "Unix&Linux" there's one more approach:

awk '{print $5}' < /proc/$pid/stat

or, more safely,

perl -l -0777 -ne '@f = /\(.*\)|\S+/g; print $f[4]' /proc/$pid/stat

See details and comments in the linked answer.

0
laughing_man On

I wrote a small script for this purpose.

Code

#!/bin/bash 
MY_GROUP_ID=$1
A="$(ps -e -o pgid,pid= | grep [0-9])"
#printf "$A\n"
IFS=$'\n'
for i in $A; do
    GROUP_ID=$(printf "$i" | awk -F ' ' '{print $1}')
    PID=$(printf "$i" | awk -F ' ' '{print $2}')
    if [ "$GROUP_ID" = "$MY_GROUP_ID" ]; then
        printf "$PID\n"
    fi
done
unset IFS

Usage

./test_script.sh (group ID you want to select for)

Explanation

  1. I'm assuming you know some Linux utilities already. This is written for bash shell only.
  2. ps -e -o pgid,pid= simply prints out all the processes with the first value of each line being its group id, and the second value being its process ID, separated by a space.
  3. grep removes unnecessary header lines.
  4. IFS is a really important internal variable. What this does is regulate how a string is delimited. The for construct automatically delimits a string using a space character, but if the IFS variable is set to new line, this delimits using this new whitespace character. This ensures that each iteration variable is a line from A.
  5. For each line, we use awk to get the first value - this is the group ID, and the second value - this is the PID.
  6. If the group ID matches what you want, then print out the corresponding PID.
  7. After you are done, you must unset IFS to its default value so that it does not linger around with its changed state.

Remarks

I hope that helps. It works for me. It's not very complicated once you understand how awk and ps works. The rest is just parsing. If you want to pass the PIDs around as an array, instead of printing it as a new line, just delimit it using something else and make a global string variable that holds all the PIDs.