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:
- I have a physical (local) connection to the host, where I’m using mutt to look at emails.
- I have an idle ssh connection.
- 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”