Use a different escape sequence for magenta.
[profile.git] / phier
1 #!/bin/bash
2 #
3 # $Id$
4 #
5 # phier: Show process tree incorporating a process.
6 # Notes: phier functions similarly (but not identically) to Solaris ptree.
7 # Usage: phier [-s <search>] <pid>
8 # Usage: phier [-s <search>] [-u <user>] [-x] <process>
9 # Options: -s <search>   Stop hierarchy at this process name.
10 #          -u <user>     Start search from processes owned by user.
11 #          -x            Match process name exactly.
12 # Example: phier -s sshd $$
13 # Example: phier -s sshd -u iain nxagent
14 #
15
16 function find_parent() {
17   child="$1"; shift
18   top="$1"; shift
19
20   if [ -z "$child" ]; then
21     echo >&2 "No child to find."
22     return 1
23   fi
24
25   cmd=$(ps -o comm= -p $child)
26   pid=$(ps -o pid= -p $child)
27   ppid=$(ps -o ppid= -p $child)
28
29 # echo >&2 "Finding from $child ($top) $pid/$ppid/$cmd"
30
31   if [ -z "$pid" ]; then
32     echo >&2 "Can't find PID $child!"
33     return 1
34   fi
35
36   if [ ! -z "$top" ]; then
37     if [ "$cmd" = "$top" ]; then
38       echo $child
39       return 0
40     fi
41   fi
42
43   if [ $pid = 1 -o $ppid = 1 ]; then
44     echo $pid
45     return 0
46   fi
47
48   find_parent $ppid $top
49   return $?
50 }
51
52 # Parse arguments.
53 children=
54 top=
55 pgrep_opts=
56 while getopts ":s:u:x" opt; do
57   case $opt in
58     s) top="$OPTARG";;
59     u) pgrep_opts="$pgrep_opts -u $OPTARG";;
60     x) pgrep_opts="$pgrep_opts -x"
61   esac
62 done
63 shift $((OPTIND-1))
64
65 if [ $# -lt 1 ]; then
66   echo >&2 "phier: Print process hierarchy for a process."
67   echo >&2 "Usage: phier [-s <search>] <pid>"
68   echo >&2 "Usage: phier [-s <search>] [-u <user>] [-x] <process>"
69   echo >&2 "Options: -s <search>   Stop hierarchy at this process name."
70   echo >&2 "         -u <user>     Start search from processes owned by user."
71   echo >&2 "         -x            Match process name exactly."
72   echo >&2 "Example: phier -s sshd $$"
73   echo >&2 "Example: phier -s sshd -u iain nxagent"
74   exit 1
75 fi
76
77 children="$1"; shift
78 if ! echo "$children" | grep -qs '^[0-9]*$'; then
79   children=$(pgrep $pgrep_opts "$children")
80 fi
81
82 errors=0
83 for child in $children; do
84   parent=$(find_parent "$child" "$top")
85   if [ $? = 0 ]; then
86     pstree -ulap $parent
87   else
88     errors=$((errors+1))
89   fi
90 done
91
92 exit $errors