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