#!/bin/bash
+#
+# $Id$
+#
+# phier: Show process tree incorporating a process.
+# Notes: phier functions similarly (but not identically) to Solaris ptree.
+# Usage: phier [-s <search>] <pid>
+# Usage: phier [-s <search>] [-u <user>] [-x] <process>
+# Options: -s <search> Stop hierarchy at this process name.
+# -u <user> Start search from processes owned by user.
+# -x Match process name exactly.
+# Example: phier -s sshd $$
+# Example: phier -s sshd -u iain nxagent
+#
function find_parent() {
child="$1"; shift
top="$1"; shift
+ if [ -z "$child" ]; then
+ echo >&2 "No child to find."
+ return 1
+ fi
+
cmd=$(ps -o comm= -p $child)
pid=$(ps -o pid= -p $child)
ppid=$(ps -o ppid= -p $child)
fi
fi
- if [ $ppid = 1 ]; then
+ if [ $pid = 1 -o $ppid = 1 ]; then
echo $pid
return 0
fi
return $?
}
+# Parse arguments.
+children=
+top=
+pgrep_opts=
+while getopts ":s:u:x" opt; do
+ case $opt in
+ s) top="$OPTARG";;
+ u) pgrep_opts="$pgrep_opts -u $OPTARG";;
+ x) pgrep_opts="$pgrep_opts -x"
+ esac
+done
+shift $((OPTIND-1))
+
if [ $# -lt 1 ]; then
echo >&2 "phier: Print process hierarchy for a process."
- echo >&2 "Usage: phier <pid> [<search>]"
- echo >&2 "Notes: If a search term is given the hierarchy will stop after finding a"
- echo >&2 " process matching that search term."
- echo >&2 "Example: phier $$ sshd"
+ echo >&2 "Usage: phier [-s <search>] <pid>"
+ echo >&2 "Usage: phier [-s <search>] [-u <user>] [-x] <process>"
+ echo >&2 "Options: -s <search> Stop hierarchy at this process name."
+ echo >&2 " -u <user> Start search from processes owned by user."
+ echo >&2 " -x Match process name exactly."
+ echo >&2 "Example: phier -s sshd $$"
+ echo >&2 "Example: phier -s sshd -u iain nxagent"
exit 1
fi
-parent=$(find_parent ${1+"$@"})
-if [ $? = 0 ]; then
- pstree -ulap $parent
-else
- exit 1
+children="$1"; shift
+if ! echo "$children" | grep -qs '^[0-9]*$'; then
+ children=$(pgrep $pgrep_opts "$children")
fi
+
+errors=0
+for child in $children; do
+ parent=$(find_parent "$child" "$top")
+ if [ $? = 0 ]; then
+ pstree -ulap $parent
+ else
+ errors=$((errors+1))
+ fi
+done
+
+exit $errors