initial import from ~/bin - plstree - ps and ls displayed as a tree
(HTM) git clone git://bitreich.org/plstree git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/plstree
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) Tags
(DIR) README
---
(DIR) commit 35d52859f6fcd9f3d9e411584784f4ccd4b75b87
(HTM) Author: Josuah Demangeon <mail@josuah.net>
Date: Thu, 19 Apr 2018 04:02:41 +0200
initial import from ~/bin
Diffstat:
A lstree | 98 +++++++++++++++++++++++++++++++
A pstree | 122 +++++++++++++++++++++++++++++++
A tree | 76 +++++++++++++++++++++++++++++++
3 files changed, 296 insertions(+), 0 deletions(-)
---
(DIR) diff --git a/lstree b/lstree
@@ -0,0 +1,98 @@
+#!/usr/bin/awk -f
+
+# list paths in a tree with some stat infos
+
+# Use find(1) walk the entire tree and then call ls -ld with all the
+# result (ls sort the list itself) with the paths displayed as a tree:
+#
+# drwxr-xr-x 2 josuah josuah 512 Feb 16 13:19 |- .ssh
+# -rw-r--r-- 1 josuah josuah 870 Feb 9 02:24 | `- config
+# drwxr-xr-x 2 josuah josuah 1536 Feb 18 21:24 |- bin
+# -rwxr-xr-x 1 josuah josuah 1351 Feb 18 22:30 | |- lt
+# -rwxr-xr-x 1 josuah josuah 565 Feb 17 19:53 | |- mfilter
+# -rwxr-xr-x 1 josuah josuah 5430 Feb 17 19:51 | `- xdg-open
+# -rwxr-xr-x 1 josuah josuah 468 Feb 17 19:55 ...
+
+BEGIN {
+ LINE = "| ";
+ NODE = "|- ";
+ TAIL = "`- ";
+ VOID = " ";
+
+ num = list(entries, ARGC == 1 ? "." : ARGV[1]);
+ tree(entries, num);
+
+ for (l = 1; l <= num; l++) {
+ for (i = 1; entries[l":"i] != ""; i++)
+ printf("%s", entries[l":"i]);
+ printf("%s\n", entries[l"name"]);
+ }
+}
+
+# Get a recursive list of all entries into entries[] with entries[i:j]
+# holding the component j of the path i, and 0 has all the -l details,
+# then return the number of entries in entries[].
+#
+# [ 1:[ 0:"-rw-r--r-- 1 root root 341 Mar 13 10:50",
+# 1:"etc" ],
+# 2:[ 0:"drwxr-xr-x 28 root root 4096 Mar 13 10:50",
+# 1:"etc",
+# 2:"sv" ],
+# 3:[ 0:"drwxr-xr-x 2 root root 4096 Mar 13 10:50",
+# 1:"etc",
+# 2:"tor" ] ]
+#
+# Only the leaves are present, the intermediates components are LINE or
+# NODE if just before a leave
+#
+# [ 1:[ 1:LINE, 2:LINE, 3:LINE, 4:LINE, 5:NODE, 6:"filename" ] ]
+
+function list(entries, path)
+{
+ cmd = "cd '" path "' && exec find ." \
+ " -name '*.git' -prune -o" \
+ " -name 'CVS' -prune -o" \
+ " -exec ls -ld {} +";
+
+ for (num = 0; cmd | getline; num++) {
+ sub(" \\.$", "", $0);
+ sub(" -> .*", "", $0);
+ infos = $0;
+ sub(" \\./.*", "", infos);
+ sub(".* \\./", "./", $0);
+
+ entries[num"path"] = $0;
+ count = split($0, path_v, "/");
+ for (i = 2; i < count; i++)
+ entries[num":"i] = LINE;
+
+ entries[num":"count] = NODE;
+ entries[num":"1] = infos " ";
+ entries[num"name"] = path_v[count];
+ }
+ close(cmd);
+
+ return num - 1;
+}
+
+# Transform entries into a tree by replacing some LINE by VOID when needed.
+# The tree is walked from the bottom to the top, and column by column
+# toward the right until an empty column is met.
+
+function tree(entries, num)
+{
+ for (i = 2; !stop; i++) {
+ stop = tail = 1;
+ for (l = num; l > 0; l--) {
+ if (entries[l":"i] == LINE && tail) {
+ entries[l":"i] = VOID;
+ stop = 0;
+ } else if (entries[l":"i] == NODE && tail) {
+ entries[l":"i] = TAIL;
+ tail = stop = 0;
+ } else if (!entries[l":"i]) {
+ tail = 1;
+ }
+ }
+ }
+}
(DIR) diff --git a/pstree b/pstree
@@ -0,0 +1,122 @@
+#!/usr/bin/awk -f
+
+# pstree implementation in awk
+
+# Use ps(1) to generate a list of pid, ppid and other properties with
+# the command name, displayed as a tree built from the pid-ppid pairs:
+#
+# USER TT NI PID STAT COMMAND
+# root ? 0 1 Ss runit
+# josuah ? 0 22437 S |- startx
+# josuah ? 0 22451 S | `- xinit
+# root tty7 0 22452 Rsl+ | |- Xorg
+# josuah ? 0 22457 S | `- dwm
+# josuah ? 0 24882 S `- runsvdir
+# josuah ? 0 24884 S |- runsv
+# josuah ? 0 24887 S | |- svlogd
+# josuah ? 0 24890 S | `- ratox
+# josuah ? 0 24885 S `- runsv
+# josuah ? 0 24405 S |- tor
+# josuah ? 0 24889 S `- svlogd
+
+BEGIN {
+ LINE = "| ";
+ NODE = "|- ";
+ TAIL = "`- ";
+ VOID = " ";
+
+ list(entries);
+ NUM = 1; fill(entries, 1, 0);
+ tree(entries, NUM);
+
+ for (i = 1; i < NUM; i++) {
+ printf("%s", entries[i":info"]);
+ for (j = 1; entries[i":"j] != ""; j++)
+ printf("%s", entries[i":"j]);
+ printf("%s\n", entries[i":comm"]);
+ }
+}
+
+# Build a relational database in <entries> from the output of ps: The
+# parent pid (ppid) -> pid pairs are used to accumulate a list of child
+# pid (serialized into a csv: ",234,532,454") later used for building
+# the tree.
+#
+# For each pid, "info" and "comm" are saved as well.
+
+function list(entries)
+{
+ opt = "-o ppid,user,tty,pid,stat,comm"
+ cmd = "exec ps -ax " opt " 2>/dev/null";
+ if (!(cmd | getline)) {
+ cmd = "exec ps " opt
+ cmd | getline;
+ }
+ sub(" *[^ ]+", "");
+ print $0;
+
+ for (num = 0; cmd | getline; num++) {
+ ppid = $1; pid = $4;
+ entries[ppid"cpid"] = entries[ppid"cpid"] "," pid;
+ sub(" *[^ ]+", "");
+ sub(" *[^ ]+ + *[^ ]+ + *[^ ]+ + *[^ ]+ +", "&\t");
+ split($0, info, "\t");
+ entries[pid"info"] = info[1];
+ entries[pid"comm"] = info[2];
+ }
+ close(cmd);
+
+ return num - 1;
+}
+
+# Using the informations from the child pid in entries, build the absolute
+# path from PID 1 to each pid:
+#
+# [ 1:[ 1:"1" ],
+# 2:[ 1:"1", 2:"456" ],
+# 3:[ 1:"1", 2:"456", 3:"1623" ],
+# 4:[ 1:"1", 2:"456", 3:"1721" ] ]
+#
+# With also ":info" and ":comm" for every row.
+#
+# Only the leaves are present, the intermediates components are LINE or
+# NODE if just before a leave
+#
+# [ 1:[ 1:LINE, 2:LINE, 3:LINE, 4:LINE, 5:NODE, 6:"filename" ] ]
+
+function fill(entries, pid, lvl)
+{
+ for (j = 0; j < lvl; j++)
+ entries[NUM":"j] = LINE;
+ entries[NUM":"lvl] = NODE;
+ entries[NUM":comm"] = entries[pid"comm"];
+ entries[NUM":info"] = entries[pid"info"];
+ NUM++;
+ while (sub("[^,]*,", "", entries[pid"cpid"])) {
+ cpid = entries[pid"cpid"];
+ sub(",.*", "", cpid);
+ fill(entries, cpid, lvl + 1);
+ }
+}
+
+# Transform entries into a tree by replacing some LINE by VOID when needed.
+# The tree is walked from the bottom to the top, and column by column
+# toward the right until an empty column is met.
+
+function tree(entries, num)
+{
+ for (j = 0; !stop; j++) {
+ stop = tail = 1;
+ for (i = num; i > 0; i--) {
+ if (entries[i":"j] == LINE && tail) {
+ entries[i":"j] = VOID;
+ stop = 0;
+ } else if (entries[i":"j] == NODE && tail) {
+ entries[i":"j] = TAIL;
+ tail = stop = 0;
+ } else if (!entries[i":"j]) {
+ tail = 1;
+ }
+ }
+ }
+}
(DIR) diff --git a/tree b/tree
@@ -0,0 +1,76 @@
+#!/usr/bin/awk -f
+
+# convert a list of paths into a tree
+
+BEGIN {
+ LINE = "| ";
+ NODE = "|- ";
+ TAIL = "`- ";
+ VOID = " ";
+
+ num = list(entries);
+ tree(entries, num);
+ display(entries, num);
+}
+
+# Get a recursive list of all entries into entries[] with entries[i:j]
+# holding the component j of the path i, and 0 has all the -l details,
+# then return the number of entries in entries[].
+#
+# [ 1:[ 1:"etc" ],
+# 2:[ 1:"etc", 2:"sv" ],
+# 3:[ 1:"etc", 2:"tor" ] ]
+#
+# Only the leaves are present, the intermediates components are LINE or
+# NODE if just before a leave
+#
+# [ 1:[ 1:LINE, 2:LINE, 3:LINE, 4:LINE, 5:NODE, 6:"filename" ],
+# 2:[ 1:LINE, 2:LINE, 3:LINE, 4:NODE, 5:"filename" ] ]
+
+function list(entries)
+{
+ for (num = 0; getline; num++) {
+ sub("^/", "", $0);
+ sub("/$", "", $0);
+ count = split($0, nodelist, "/");
+ for (i = 1; i < count; i++)
+ entries[num":"i] = LINE;
+ entries[num":"count] = NODE;
+ entries[num"name"] = nodelist[count];
+ }
+
+ return num - 1;
+}
+
+# Transform entries into a tree by replacing some LINE by VOID when needed.
+# The tree is walked from the bottom to the top, and column by column
+# toward the right until an empty column is met which stops the algorithm.
+
+function tree(entries, num)
+{
+ for (i = 1; !stop; i++) {
+ stop = tail = 1;
+ for (l = num; l > 0; l--) {
+ if (entries[l":"i] == LINE && tail) {
+ entries[l":"i] = VOID;
+ stop = 0;
+ } else if (entries[l":"i] == NODE && tail) {
+ entries[l":"i] = TAIL;
+ tail = stop = 0;
+ } else if (!entries[l":"i]) {
+ tail = 1;
+ }
+ }
+ }
+}
+
+# Print all entries line by line.
+
+function display(entries, num)
+{
+ for (l = 1; l <= num; l++) {
+ for (i = 1; entries[l":"i] != ""; i++)
+ printf("%s", entries[l":"i]);
+ printf("%s\n", entries[l"name"]);
+ }
+}