6

I have a Python script that spawns a few subprocesses but never more than n at a time.

I want to write a shell script to confirm that it has no more than n subprocesses at any given time, but also that generally it has n processes running.

If I have the PID of the Python program inside a shell script, how do I check the number of subprocesses that that PID currently has? E.g.

python script.py &
pid=$!
while true
do
    # do something that prints number of subprocesses of
    # the process $pid to stdout
    sleep 1
done
  • 3
    You may want to look at /proc/$$/task/$$/children to get first level children – cuonglm Apr 2 '16 at 1:48
  • @cuonglm's comment is a preety good one, taps directly into procfs, but OS like Mac OSX doesn't have procfs. In that case pgrep should do it fine. – Vikyboss Apr 2 '16 at 2:32
  • 1
    @cuonglm You should post this as an answer. It's Linux-specific, but it has an advantage over portable solutions: it's atomic. – Gilles Apr 2 '16 at 21:39
  • 1
    @Gilles: If the latest stable kernel's (4.5) documentation is accurate, [/proc/<pid>/task/<tid>/children] (git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/…) atomicity requires a little extra effort: Since this interface is intended to be fast and cheap it doesn't guarantee to provide precise results and some children might be skipped, especially if they've exited right after we printed their pids, so **one need to either stop or freeze processes being inspected if precise results are needed**. – Barefoot IO Apr 3 '16 at 5:48
  • @BarefootIO Oh, damn, I thought it took the proper lock. There's no real advantage over portable methods then. Thanks. – Gilles Apr 3 '16 at 11:51
4
ps -eo ppid= | grep -Fwc $pid

If your grep does not support -w:

ps -eo ppid= | tr -d '[:blank:]' | grep -Fxc $pid

or

ps -eo ppid= | awk '$1==ppid {++i} END {print i+0}' ppid=$pid

or (clobbering the positional parameters)

set $(ps -eo ppid=); echo $#

Note that this is not atomic, so the count may be wrong if some processes die and others get spawned in the short span of time it takes to gather the data.

3

Try ps --ppid ${pid} --no-headers | wc --lines.

1

If pgrep available, filter by parent pid[-P]:

sproc_pids=( $(pgrep -P $pid) ) && echo ${#sproc_pids[@]}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.