Maybe something like:
#! /bin/bash -
pid=${1?Please give a pid}
sep=
while
[ "$pid" -gt 0 ] &&
read -r ppid name < <(ps -o ppid= -o args= -p "$pid")
do
printf "$sep%$((3+${#pid}/2))d%$((4-${#pid}/2))s%s\n" "$pid" "" "$name"
sep=$' |\n'
pid=$ppid
done
Which gives:
$ that-script "$$"
13612 /bin/zsh
|
4137 SCREEN screen -xRS main
|
4136 screen screen -xRS main
|
4130 zsh
|
4128 xterm
|
1 /sbin/init splash
That's a bit sluggish as it runs one ps
per process in the ancestry. You can improve it by running ps
to retrieve all the information at once and post process it with awk
for instance:
#! /bin/sh -
pid=${1?Please give a pid}
ps -Ao pid= -o ppid= -o args= |
awk -v p="$pid" '
{
pid = $1; ppid[pid] = $2
sub(/([[:space:]]*[[:digit:]]+){2}[[:space:]]*/, "")
args[pid] = $0
}
END {
while (p) {
printf "%s%*d%*s%s\n", sep, 3+length(p)/2, p, 4-length(p)/2, "", args[p]
p = ppid[p]
sep = " |\n"
}
}'
pstree -spa $$
uses the shell's PID as a start – Johannes Bittner Jul 28 '19 at 01:01