Gitify the working tree.
[profile.git] / opt / bin / phier
diff --git a/opt/bin/phier b/opt/bin/phier
new file mode 100755 (executable)
index 0000000..8806835
--- /dev/null
@@ -0,0 +1,90 @@
+#!/bin/bash
+#
+# 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)
+
+# echo >&2 "Finding from $child ($top) $pid/$ppid/$cmd"
+
+  if [ -z "$pid" ]; then
+    echo >&2 "Can't find PID $child!"
+    return 1
+  fi
+
+  if [ ! -z "$top" ]; then
+    if [ "$cmd" = "$top" ]; then
+      echo $child
+      return 0
+    fi
+  fi
+
+  if [ $pid = 1 -o $ppid = 1 ]; then
+    echo $pid
+    return 0
+  fi
+
+  find_parent $ppid $top
+  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 [-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
+
+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