20

In "https://stackoverflow.com/questions/13038143/how-to-get-pids-in-one-process-group-in-linux-os" I see all answers mentioning ps and none mentioning /proc.

"ps" seems to be not very portable (Android and Busybox versions expect different arguments), and I want to be able list pids with pgids with simple and portable tools.

In /proc/.../status I see Tgid: (thread group ID), Gid: (group id for security, not for grouping processes together), but not PGid:...

What are other (not using ps) ways of getting pgid from pid?

Vi.
  • 5,528
  • 7
  • 34
  • 68

1 Answers1

30

You can look at field 5th in output of /proc/[pid]/stat.

$ ps -ejH | grep firefox
 3043  2683  2683 ?        00:00:21   firefox

$ < /proc/3043/stat sed -n '$s/.*) [^ ]* [^ ]* \([^ ]*\).*/\1/p'
2683

From man proc:

/proc/[pid]/stat
              Status information about the process.  This is used by ps(1).  It is defined in /usr/src/linux/fs/proc/array.c.

              The fields, in order, with their proper scanf(3) format specifiers, are:

              pid %d      The process ID.

              comm %s     The filename of the executable, in parentheses.  This is visible whether or not the executable is swapped out.

              state %c    One character from the string "RSDZTW" where R is running, S is sleeping in an interruptible wait, D is waiting in
                          uninterruptible disk sleep, Z is zombie, T is traced or stopped (on a signal), and W is paging.

              ppid %d     The PID of the parent.

              pgrp %d     The process group ID of the process.

              session %d  The session ID of the process.

Note that you cannot use:

awk '{print $5}'

Because that file is not a blank separated list. The second field (the process name may contain blanks or even newline characters). For instance, most of the threads of firefox typically have space characters in their name.

So you need to print the 3rd field after the last occurrence of a ) character in there.

jpaugh
  • 319
  • 2
  • 13
cuonglm
  • 150,973
  • 38
  • 327
  • 406
  • Note that `awk '{print $5}'` is not guaranteed to give you the right answer as the process name (second field) may contain space or newline characters. – Stéphane Chazelas May 27 '14 at 15:54
  • How to reliably parse /proc/.../stat ? – Vi. May 27 '14 at 15:56
  • 3
    @Vi, see [that answer](http://unix.stackexchange.com/a/132081/22565) `perl -l -0777 -ne '@f = /\(.*\)|\S+/g; print $f[4]' "/proc/$pid/stat"` or `p=$(cat "/proc/$pid/stat") && set ${p##*')'} && echo "$3"` – Stéphane Chazelas May 27 '14 at 16:03
  • @StephaneChazelas: Thanks, I have updated my answer! – cuonglm May 27 '14 at 16:34
  • It's more process names than file names. The problem will typically occur with processes that change their name (from the one they get from the name of the last file they executed). – Stéphane Chazelas May 27 '14 at 16:45
  • @Stéphane Chazelas - you forgot one of the `/gs` modifiers on the Perl regexp when you copied **that answer**. Perl needs both `/s` and `/g` otherwise `.` won't match the newline. – Ian D. Allen Jun 02 '22 at 03:00