Use root‑tail & top instead of conky

Conky is good for displaying things on the desktop. But it has a few disadvantages:

  • There's no option to continuously show the output of a command (or file), like tail -f or dmesg -w, and update conky's output as that output grows. [X]
  • Some internal conky commands measuring system resources are buggy (and have been for a long time).

Alternatives

One could use gkrellm, which is similar to conky, better in some areas, less so in others.

One could make a transparent terminal, stick it to the desktop, and make it run the command that (continuously) produces the desired output.

root-tail

Or one could use root-tail. It can display log files, but also command output. It is specifically designed for use case [X] - but less so for others.

For the perfect setup, we will rely on the man page and even look at the source. Two exaples - the easier one first:

Show latest journal entries

Systemd's journalctl has a --follow option. Basically, we could just pipe that into root-tail:

journalctl -f | root-tail -

Most likely this will use a sub-optimal font. Find a suitable monospaced one with xfontsel (or just use fixed).
We can also tell journalctl to drop the hostname and headers.
Further we can tell root-tail to drop the description (e.g. [stdin]) and use a milder colour.
And lastly add a geometry string to move the window to the bootm left, make it wider and show only ~15 lines:

journalctl -f --no-hostname -q | root-tail --geometry 1500x200+10-10 -fn '-*-screen-medium-r-*-*-14-*-*-*-*-*-iso8859-*' -,"#ccc",

Piping top into root-tail

At first I was amazed that this was even possible at all!
top has a batch mode ... useful for sending output from top to other programs. Again, we can start here:

top -b | root-tail -

And again, it will not only look horrible but be useless, too, because top outputs way too much. We need to tell it to show fewer lines, and probably also fewer columns.

top cannot be customised by editing config files directly. One has to make the desired changes interactively and save them to a profile. To create one only for piping root-tail into top, first make a symbolic link to top in a suitable directory, then start it normally, without batch mode:

ln -s $(which top) top-root-tail
./top-root-tail

Goal: display top 5 CPU consuming and top 5 memory consuming commands

Let's open top's man page and have a good look at chapter 4.
Press t, l and m until the summary above the task list is completely gone. Press n and enter the number of tasks to display. Press f and select the fields we want to see. Press j and J to play with alignment until it looks good.
After making the desired changes, enter W to save. Now, every time we start top as top-root-tail it will look like that.

Now it will look much better when we pipe that into root-tail, but we need to adjust its height so that it displays only the latest update.

top can also display more than one "window" (try A and read chapter 5), so we could achieve our goal with just one top instance. But in batch mode, this doesn't look good. There's no separation between the two windows.
Or we could pipe two tops into one root-tail, but root-tail displays the data as it comes in line by line, and would mix up the two outputs.

Here's a wrapper script that uses two customised tops piped into two suitably sized root-tails, positioned together:

sh
#!/bin/sh width=38 height=6 # good for testing geometry #frame="--frame" edge=right # or left - defaults to right offset1=40 # from top of screen margin=10 # margin between lower and upper root-tail font='-*-*-*-r-*-*-12-*-*-*-c-*-iso8859-*' # xlsfonts to get character width & height fontdata="$(xlsfonts -lumo -fn "$font"|awk '/max/{gsub(/\(|\)/,"");print substr($0,index($0,$3))}')" charwidth="$(echo "$fontdata"|cut -d, -f3)" charheight="$(( $(echo "$fontdata"|cut -d, -f4) + $(echo "$fontdata"|cut -d, -f5) ))" geom="$((charwidth*width))x$((charheight*height))" printf "character width: $charwidth\ncharacter height: $charheight\ngeometry: $geom\n" offset2=$((offset1 + margin + charheight*height)) [ $edge = left ] && edge="+" || edge="-" unset fontdata charwidth charheight height ./top-root-tail-cpu -s -w${width} -b | \ root-tail $frame --noflicker --geometry ${geom}${edge}0+$offset1 -fn "$font" -,"#FFBD30", & ./top-root-tail-mem -s -w${width} -b | \ root-tail $frame --noflicker --geometry ${geom}${edge}0+$offset2 -fn "$font" -,"#28CA41",

Caveat 1: no Unicode, only bitmapped fonts

root-tail only uses the old X11 fonts.
It does not support Unicode fonts (with a large set of characters from different languages, but also icons and such), only a sort of extended ASCII.
The former is labeled iso10646 in the font name, the latter iso8859.

Caveat 2: changing the wallpaper makes root-tail flicker

root-tail only updates its part of the root window when new log lines are coming in. When the root window background changes (periodically - maybe xplanet is doing things, maybe there's a slideshow running), there will be no root-tail output visible for a while. This can be avoided by sending SIGUSR2to root-tail, which forces a refresh:

sh
signal=SIGUSR2 for pid in $(pidof root-tail); do echo "kill -s $signal $pid" kill -s $signal $pid done

Even so, there's a slight flicker. root-tails --noflicker option doesn't seem to help much, either.