View running processes and their children

View running processes and their children

When using bash, ps is a very powerful tool for viewing running processes. I have built a script/library for manipulating its output to create trees for either running shell scripts, or user sessions. This allows me to see who is doing/executing what on a linux host at a point in time.

Continuing with some of my bash notes, I was reminded of this recently during a discussion about identifying process ids. I created this when I wanted to know one of two things:

  • What scripts were running at that point in time, and which command(s) they were currently executing (to get an idea of progress).
  • Who was running what processes/scripts on the server.

I was quickly able to view all running processes with ps, but getting the output I desired became more difficult. In the end I created functions for manipulating lists of IDs and iterating over them to get all the process ids which sat beneath each one.

Getting the Library

This script (and others to come) is hosted using github. If you’d like to pull a copy of the bash library from git (feel free). Install git, and then check out the whole library:

# I prefer to have this in the base of my home
cd ~/

# Clone the repository (pulling everything down)
git clone https://github.com/d-roman-halliday/bash_library.git

# Getting updates (when I add new stuff to it)
cd ~/bash_library
git pull

Or, if you just want the one script, copy it from github. Or see below:

# Pull raw text using wget
wget https://raw.githubusercontent.com/d-roman-halliday/bash_library/master/process_tree.bash

View the script on github: process_tree.bash

Including the Library

To load a library into a session (so its functions can be called like applications) precede the library script reference with a dot:

. ~/bash_library/process_tree.bash

Without doing this, the below examples won’t work. Note that a library can be included in another bash script, or for all sessions by adding it to the bashrc file.

Note: I’ve prepended the functions in my library:

  • bf – Bash Function: A user facing bash function, prepended for clarity when using tab completion.
  • hbf – Helper Bash Function: Bash functions called by the user facing functions, with a different start to limit options for tab completion.

Script View

This shows all the running shell scripts and any processes beneath them.

Test scripts

The first script waits for 10 minutes. The second script calls the first multiple times in parallel (creating a collection of subtasks). The third calls the second multiple times (creating a lot of nesting).

test1.sh

#!/bin/bash
echo " pid: $$"
echo "bpid: $BASHPID"

sleep 10m

echo "done"
exit 0

test2.sh

#!/bin/bash
~/test1.sh &
~/test1.sh &
~/test1.sh &
~/test1.sh &
~/test1.sh &
~/test1.sh &
wait
exit 0

test3.sh

#!/bin/bash
~/test2.sh &
~/test2.sh &
~/test2.sh &
wait
exit 0

Sample Output

The command is on the first line, everything else is the output of the script. Showing (in this instance) one copy of test2.sh running (with 6 copies of script1.sh beneath it). And one instance of test3.sh running (with the respective script2.sh and script1.sh beneath that).

david@roman-halliday:~$ bf_script_view
UID        PID  PPID  C STIME TTY      STAT   TIME CMD
david     8557 26864  0 16:38 pts/2    S+     0:00 /bin/bash ./test2.sh
david     8558  8557  0 16:38 pts/2    S+     0:00  \_ /bin/bash /home/david/test1.sh
david     8569  8558  0 16:38 pts/2    S+     0:00  |   \_ sleep 10m
david     8559  8557  0 16:38 pts/2    S+     0:00  \_ /bin/bash /home/david/test1.sh
david     8568  8559  0 16:38 pts/2    S+     0:00  |   \_ sleep 10m
david     8560  8557  0 16:38 pts/2    S+     0:00  \_ /bin/bash /home/david/test1.sh
david     8567  8560  0 16:38 pts/2    S+     0:00  |   \_ sleep 10m
david     8561  8557  0 16:38 pts/2    S+     0:00  \_ /bin/bash /home/david/test1.sh
david     8566  8561  0 16:38 pts/2    S+     0:00  |   \_ sleep 10m
david     8562  8557  0 16:38 pts/2    S+     0:00  \_ /bin/bash /home/david/test1.sh
david     8565  8562  0 16:38 pts/2    S+     0:00  |   \_ sleep 10m
david     8563  8557  0 16:38 pts/2    S+     0:00  \_ /bin/bash /home/david/test1.sh
david     8564  8563  0 16:38 pts/2    S+     0:00      \_ sleep 10m
UID        PID  PPID  C STIME TTY      STAT   TIME CMD
david     8570 26908  0 16:38 pts/3    S+     0:00 /bin/bash ./test3.sh
david     8571  8570  0 16:38 pts/3    S+     0:00  \_ /bin/bash /home/david/test2.sh
david     8581  8571  0 16:38 pts/3    S+     0:00  |   \_ /bin/bash /home/david/test1.sh
david     8601  8581  0 16:38 pts/3    S+     0:00  |   |   \_ sleep 10m
david     8582  8571  0 16:38 pts/3    S+     0:00  |   \_ /bin/bash /home/david/test1.sh
david     8596  8582  0 16:38 pts/3    S+     0:00  |   |   \_ sleep 10m
david     8583  8571  0 16:38 pts/3    S+     0:00  |   \_ /bin/bash /home/david/test1.sh
david     8598  8583  0 16:38 pts/3    S+     0:00  |   |   \_ sleep 10m
david     8584  8571  0 16:38 pts/3    S+     0:00  |   \_ /bin/bash /home/david/test1.sh
david     8608  8584  0 16:38 pts/3    S+     0:00  |   |   \_ sleep 10m
david     8585  8571  0 16:38 pts/3    S+     0:00  |   \_ /bin/bash /home/david/test1.sh
david     8599  8585  0 16:38 pts/3    S+     0:00  |   |   \_ sleep 10m
david     8586  8571  0 16:38 pts/3    S+     0:00  |   \_ /bin/bash /home/david/test1.sh
david     8604  8586  0 16:38 pts/3    S+     0:00  |       \_ sleep 10m
david     8572  8570  0 16:38 pts/3    S+     0:00  \_ /bin/bash /home/david/test2.sh
david     8575  8572  0 16:38 pts/3    S+     0:00  |   \_ /bin/bash /home/david/test1.sh
david     8609  8575  0 16:38 pts/3    S+     0:00  |   |   \_ sleep 10m
david     8576  8572  0 16:38 pts/3    S+     0:00  |   \_ /bin/bash /home/david/test1.sh
david     8595  8576  0 16:38 pts/3    S+     0:00  |   |   \_ sleep 10m
david     8577  8572  0 16:38 pts/3    S+     0:00  |   \_ /bin/bash /home/david/test1.sh
david     8593  8577  0 16:38 pts/3    S+     0:00  |   |   \_ sleep 10m
david     8578  8572  0 16:38 pts/3    S+     0:00  |   \_ /bin/bash /home/david/test1.sh
david     8594  8578  0 16:38 pts/3    S+     0:00  |   |   \_ sleep 10m
david     8579  8572  0 16:38 pts/3    S+     0:00  |   \_ /bin/bash /home/david/test1.sh
david     8597  8579  0 16:38 pts/3    S+     0:00  |   |   \_ sleep 10m
david     8580  8572  0 16:38 pts/3    S+     0:00  |   \_ /bin/bash /home/david/test1.sh
david     8603  8580  0 16:38 pts/3    S+     0:00  |       \_ sleep 10m
david     8573  8570  0 16:38 pts/3    S+     0:00  \_ /bin/bash /home/david/test2.sh
david     8574  8573  0 16:38 pts/3    S+     0:00      \_ /bin/bash /home/david/test1.sh
david     8592  8574  0 16:38 pts/3    S+     0:00      |   \_ sleep 10m
david     8587  8573  0 16:38 pts/3    S+     0:00      \_ /bin/bash /home/david/test1.sh
david     8607  8587  0 16:38 pts/3    S+     0:00      |   \_ sleep 10m
david     8588  8573  0 16:38 pts/3    S+     0:00      \_ /bin/bash /home/david/test1.sh
david     8600  8588  0 16:38 pts/3    S+     0:00      |   \_ sleep 10m
david     8589  8573  0 16:38 pts/3    S+     0:00      \_ /bin/bash /home/david/test1.sh
david     8606  8589  0 16:38 pts/3    S+     0:00      |   \_ sleep 10m
david     8590  8573  0 16:38 pts/3    S+     0:00      \_ /bin/bash /home/david/test1.sh
david     8605  8590  0 16:38 pts/3    S+     0:00      |   \_ sleep 10m
david     8591  8573  0 16:38 pts/3    S+     0:00      \_ /bin/bash /home/david/test1.sh
david     8602  8591  0 16:38 pts/3    S+     0:00          \_ sleep 10m

Session View

This shows all sessions (active or disconnected) on the server, and like with the shell scripts above it creates a tree of all the processes that each session is running.

In the below example, we can see that:

  1. I have a physical (local) connection to the host, where I’m using mutt to look at emails.
  2. I have an idle ssh connection.
  3. I have two screen sessions (both idle), the second with two tabs running.
david@roman-halliday:~$ bf_session_view
UID        PID  PPID  C STIME TTY      STAT   TIME CMD
root      1671     1  0 Mar20 tty1     Ss     0:00 /bin/login --
david    23310  1671  0 Apr10 tty1     S      0:00  \_ -bash
david    23342 23310  0 Apr10 tty1     S+     0:04      \_ mutt
UID        PID  PPID  C STIME TTY      STAT   TIME CMD
david     4470  4399  0 12:35 ?        S      0:01 sshd: david@pts/0
david     4471  4470  0 12:35 pts/0    Ss     0:01  \_ -bash
UID        PID  PPID  C STIME TTY      STAT   TIME CMD
david     5959     1  0 15:48 ?        Ss     0:00 SCREEN
david     5960  5959  0 15:48 pts/5    Ss+    0:00  \_ /bin/bash
UID        PID  PPID  C STIME TTY      STAT   TIME CMD
david    26780     1  0 Aug10 ?        Ss     0:00 SCREEN
david    26864 26780  0 Aug10 pts/2    Ss+    0:00  \_ /bin/bash
david    26908 26780  0 Aug10 pts/3    Ss+    0:00  \_ /bin/bash

Looking at those old screen sessions reminds me of the xkcd comic Admin Mourning.

 

One Reply to “View running processes and their children”

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.