|
|
ptree - plstree - ps and ls displayed as a tree |
|
|
 |
git clone git://bitreich.org/plstree git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/plstree (git://bitreich.org) |
|
|
 |
Log |
|
|
 |
Files |
|
|
 |
Refs |
|
|
 |
Tags |
|
|
 |
README |
|
|
|
--- |
|
|
|
ptree (3515B) |
|
|
|
--- |
|
|
|
1 #!/usr/bin/awk -f |
|
|
|
2 |
|
|
|
3 # pstree implementation in awk |
|
|
|
4 |
|
|
|
5 # Use ps(1) to generate a list of pid, ppid and other properties with |
|
|
|
6 # the command name, displayed as a tree built from the pid-ppid pairs: |
|
|
|
7 # |
|
|
|
8 # USER TT NI PID STAT COMMAND |
|
|
|
9 # root ? 0 1 Ss runit |
|
|
|
10 # josuah ? 0 22437 S ├─ startx |
|
|
|
11 # josuah ? 0 22451 S │ └─ xinit |
|
|
|
12 # root tty7 0 22452 Rsl+ │ ├─ Xorg |
|
|
|
13 # josuah ? 0 22457 S │ └─ dwm |
|
|
|
14 # josuah ? 0 24882 S └─ runsvdir |
|
|
|
15 # josuah ? 0 24884 S ├─ runsv |
|
|
|
16 # josuah ? 0 24887 S │ ├─ svlogd |
|
|
|
17 # josuah ? 0 24890 S │ └─ ratox |
|
|
|
18 # josuah ? 0 24885 S └─ runsv |
|
|
|
19 # josuah ? 0 24405 S ├─ tor |
|
|
|
20 # josuah ? 0 24889 S └─ svlogd |
|
|
|
21 |
|
|
|
22 BEGIN { |
|
|
|
23 LINE = "│ "; |
|
|
|
24 NODE = "├─ "; |
|
|
|
25 TAIL = "└─ "; |
|
|
|
26 VOID = " "; |
|
|
|
27 |
|
|
|
28 list(entries); |
|
|
|
29 NUM = 1; fill(entries, 1, 0); |
|
|
|
30 tree(entries, NUM); |
|
|
|
31 |
|
|
|
32 for (i = 1; i < NUM; i++) { |
|
|
|
33 printf("%s", entries[i":info"]); |
|
|
|
34 for (j = 1; entries[i":"j] != ""; j++) |
|
|
|
35 printf("%s", entries[i":"j]); |
|
|
|
36 printf("%-" 30 - j * 3 "s", entries[i":comm"]); |
|
|
|
37 print(entries[i":args"]); |
|
|
|
38 } |
|
|
|
39 } |
|
|
|
40 |
|
|
|
41 # Build a relational database in <entries> from the output of ps: The |
|
|
|
42 # parent pid (ppid) -> pid pairs are used to accumulate a list of child |
|
|
|
43 # pid (serialized into a csv: ",234,532,454") later used for building |
|
|
|
44 # the tree. |
|
|
|
45 # |
|
|
|
46 # For each pid, "info" and "comm" are saved as well. |
|
|
|
47 |
|
|
|
48 function list(entries) |
|
|
|
49 { |
|
|
|
50 opt = "-o ppid,user,vsz,pid,stat,comm,args" |
|
|
|
51 cmd = "exec ps -ax " opt " 2>/dev/null"; |
|
|
|
52 if (!(cmd | getline)) { |
|
|
|
53 cmd = "exec ps " opt |
|
|
|
54 cmd | getline; |
|
|
|
55 } |
|
|
|
56 sub(" *[^ ]+", ""); |
|
|
|
57 print $0; |
|
|
|
58 |
|
|
|
59 for (num = 0; cmd | getline; num++) { |
|
|
|
60 ppid = $1; pid = $4; |
|
|
|
61 entries[ppid"cpid"] = entries[ppid"cpid"] "," pid; |
|
|
|
62 sub(" *[^ ]+", ""); |
|
|
|
63 sub(" *[^ ]+ + *[^ ]+ + *[^ ]+ + *[^ ]+ +", "&\t"); |
|
|
|
64 sub("[^\t]+ [^ ]+ +", "&\t"); |
|
|
|
65 split($0, info, "\t"); |
|
|
|
66 sub(" *$" , "", info[2]); |
|
|
|
67 entries[pid"info"] = info[1]; |
|
|
|
68 entries[pid"comm"] = info[2]; |
|
|
|
69 entries[pid"args"] = info[3]; |
|
|
|
70 } |
|
|
|
71 close(cmd); |
|
|
|
72 |
|
|
|
73 return num - 1; |
|
|
|
74 } |
|
|
|
75 |
|
|
|
76 # Using the informations from the child pid in entries, build the absolute |
|
|
|
77 # path from PID 1 to each pid: |
|
|
|
78 # |
|
|
|
79 # [ 1:[ 1:"1" ], |
|
|
|
80 # 2:[ 1:"1", 2:"456" ], |
|
|
|
81 # 3:[ 1:"1", 2:"456", 3:"1623" ], |
|
|
|
82 # 4:[ 1:"1", 2:"456", 3:"1721" ] ] |
|
|
|
83 # |
|
|
|
84 # With also ":info" and ":comm" for every row. |
|
|
|
85 # |
|
|
|
86 # Only the leaves are present, the intermediates components are LINE or |
|
|
|
87 # NODE if just before a leave |
|
|
|
88 # |
|
|
|
89 # [ 1:[ 1:LINE, 2:LINE, 3:LINE, 4:LINE, 5:NODE, 6:"filename" ] ] |
|
|
|
90 |
|
|
|
91 function fill(entries, pid, lvl) |
|
|
|
92 { |
|
|
|
93 for (j = 0; j < lvl; j++) |
|
|
|
94 entries[NUM":"j] = LINE; |
|
|
|
95 entries[NUM":"lvl] = NODE; |
|
|
|
96 entries[NUM":comm"] = entries[pid"comm"]; |
|
|
|
97 entries[NUM":args"] = entries[pid"args"]; |
|
|
|
98 entries[NUM":info"] = entries[pid"info"]; |
|
|
|
99 NUM++; |
|
|
|
100 while (sub("[^,]*,", "", entries[pid"cpid"])) { |
|
|
|
101 cpid = entries[pid"cpid"]; |
|
|
|
102 sub(",.*", "", cpid); |
|
|
|
103 fill(entries, cpid, lvl + 1); |
|
|
|
104 } |
|
|
|
105 } |
|
|
|
106 |
|
|
|
107 # Transform entries into a tree by replacing some LINE by VOID when needed. |
|
|
|
108 # The tree is walked from the bottom to the top, and column by column |
|
|
|
109 # toward the right until an empty column is met. |
|
|
|
110 |
|
|
|
111 function tree(entries, num) |
|
|
|
112 { |
|
|
|
113 for (j = 0; !stop; j++) { |
|
|
|
114 stop = tail = 1; |
|
|
|
115 for (i = num; i > 0; i--) { |
|
|
|
116 if (entries[i":"j] == LINE && tail) { |
|
|
|
117 entries[i":"j] = VOID; |
|
|
|
118 stop = 0; |
|
|
|
119 } else if (entries[i":"j] == NODE && tail) { |
|
|
|
120 entries[i":"j] = TAIL; |
|
|
|
121 tail = stop = 0; |
|
|
|
122 } else if (!entries[i":"j]) { |
|
|
|
123 tail = 1; |
|
|
|
124 } |
|
|
|
125 } |
|
|
|
126 } |
|
|
|
127 } |
|