15

I have poor eyesight that is getting worse and worse, and my work requires me to use a lot of terminal-based programmes with table-based outputs (see below). It can be very difficult to look at individual lines and access the information I need. I'm looking for a way to make the terminal show each line [EDIT:] of the background (i.e. where purple is default) in alternating colours in order to guide my eyes better. Is there a way to do this in the Ubuntu terminal, or another terminal programme that offers this option? I'm really struggling to find anything

enter image description here

[EDIT:]

@kos's response using this works with Xspec:

In ~/.bashrc:

alias colorize="perl -pe '
    if( \$. %2) {
        s/^/\e[38;5;15m/; s/^/\e[48;5;238m/
    }
    else {
        s/^/\e[38;5;0m/; s/^/\e[48;5;249m/
    }

    s/\$/\e[K/;
    s/\$/\e[0m/
'"

Usage:

<command> | colorize

However there is an issue where I cannot see my active prompt (i.e. "XSPEC12>") or what I'm typing in the prompt. Once I have hit enter, it shows up, but I can't see it whilst I'm typing

5
  • 2
    It looks like the program that you are using (XSPEC) uses an interactive tcl shell for CLI sessions. I have no experience with this, however it seems to be possible to capture and transform the tcl stdout stream as shown here - maybe you could adapt that? Commented Jun 10 at 17:46
  • Frame question: You say you want alternating colors to help compensate for bad eye sight. But... are you sure this will help? I would argue you're better off with a shell that makes a clearer separation between command outputs. for example, oh-my-zsh with (e.g.) the Jonathan theme. It draws a vertical colored line underneath each entered command.
    – Opifex
    Commented Jun 11 at 13:33
  • 2
    @Opifex That is not what OP is asking at all. OP wants to better distinguish between different lines on the terminal, even if they're part of the same command output.
    – marcelm
    Commented Jun 11 at 14:22
  • 1
    One workaround is to select the line you are interested in by triple-clicking. It will then be hilighted.
    – jpa
    Commented Jun 12 at 10:27
  • I think this is one of the things that are best implemented in the Terminal emulator itself - perhaps by an accesibility team or on request to the project itself. The default monitor in Ubuntu is Gnome Terminal (and the coloring scheme can be set in preferences if that helps) Commented Jun 12 at 19:18

4 Answers 4

12

Use a background image

Unfortunately gnome-terminal no longer has background image feature, but e.g. Konsole still does. For Konsole it is set in profile settings by creating a new color scheme.

Create an image that has stripes at the same spacing as your terminal font. It is easiest to do this by taking a screenshot and drawing on top of it:

Example background image

Set it as the terminal background and you have stripes in everything:

Example usage

Downside is that the spacing will not scale if you zoom the terminal font. Though it is possible to create multiple profiles with different font settings and corresponding background images.

2
  • 2
    For OP's specific case, this is probably the best solution, as the use they're concerned with involves running an interactive shell, which complicates things.
    – kos
    Commented Jun 12 at 11:52
  • 3
    Thanks all for your help, I managed to get this working perfectly!
    – Arianna
    Commented Jun 12 at 14:23
12

Ubuntu uses Gnome Terminal, which has an option to increase the space between its lines. The option is in the hamburger menu > Preferences > Profile > Text > Cell spacing > height:

Gnome terminal preferences

Setting the cell height spacing to 1.4 changes the output from:

Command output with default spacing

to this, where it may be easier to follow lines for you:

Command output with increased vertical spacing

In the same settings, you can also increase the font size, which may also be helpful.

8

Try this:

Put this text into striped.py:

#!/usr/bin/env python3
# -*- coding: iso-8859-1 -*-

import sys

c = ['\x1b[36m', '\x1b[37m']  # alternate between these two, for odd/even lines.

print(
    ''.join([
        c[n%2] + line 
        for n,line in enumerate(sys.stdin)
        ]),
    '\n\x1b[0m'
    )

Make it executable by chmod 755 striped.py

And then use it as in e.g. maketable | ./striped.py

... which will print every other line in different color.

To use less with this output, add its -R option as in ... | less -R.

I tried to find a pair of colors that are distinguishable yet contrasting to each other.

Example to try out

$ striped.py < /etc/os-release | less -R

More

If you wish, you can have numbered lines; that can be done (in fancy fashion) by adding

rvson = '\x1b[7m'
rvsoff = '\x1b[27m'

on lines after c = ... and then change

c[n%2] + line

with + f'{rvson}{n:>4}:{rvsoff} ' inserted, as in...

c[n%2] + f'{rvson}{n:>4}:{rvsoff} ' + line

Alternative

Use dimmed text instead of colors; change the c = ... line to

c = ['\x1b[2m', '\x1b[22m']

Noted for this: Does not work in Windows/cmd.exe, it is simply ignored.


Ref: ANSI escape code - Wikipedia


For Windows cmd users: add

import os
os.system("")

e.g. on a line after import sys - this magically initializes (some) ANSI escape code support.

"That is the Windows way" - always some kind of special magic required.


Edit 2024-06-12:
Alternative: Make a striped background, using the "same" code as above.

#!/usr/bin/env python3
# -*- coding: iso-8859-1 -*-

import os
os.system("") # make this work in Win/cmd.exe

import sys

c = [
    '\x1b[48;2;80;80;80m',
    '\x1b[48;2;100;100;100m'
    ]

print(
    ''.join([
        c[n%2] + '\x1b[2K' + line 
        for n,line in enumerate(sys.stdin)
        ])+'\x1b[0m',end=''
    )
print()

Note:
*[48;2;80;80;80m has the 4 for background color (use 3 for foreground),
and ;80;80;80 for R, G, and B - as they're the same here we get a grey tone.

Any other RGB values will also work, i.e. create your own color-version in pink;
;255;0;255 is "full" pink (bright magenta), do reduce the 255's to get a less colorful tone. Chose two slightly different tones and place them as a and b in inside c = [ a, b ]

And last but not least + '\x1b[2K' + makes the background appear on the entire line, regardless of window size, line length or height - dependent only on c[n%2] to set the color.

12
  • 1
    It's a decent approach, the only nit is that this will add two newlines at the end of the output that are not present in the input; one is due to an explicit newline character in \n\x1b[0m (you can easily fix that by chainging it to \x1b[0m), while the other has probably something to do with reading STDIN directly. I'm too rusty in Python to be able offer a solution for the latter.
    – kos
    Commented Jun 10 at 19:35
  • I consider that last newline as a "clarity enhancer", your mileage may wary. Now: I see that your edit added syntax highlighting (language: python*) - where do I find a description of that?
    – Hannu
    Commented Jun 10 at 19:42
  • 1
    Note: print(...) always has an added LF at the end. Unless you do print(... , end='') but that usually leaves your bash prompt appended to any text output, i.e. not on a new line..
    – Hannu
    Commented Jun 10 at 19:44
  • As long as the output isn't processed by something else down a pipeline, it should be fine; for the syntax highlighting thing see here (beware that the language list is probably outdated; it should be still relevant for the most part)
    – kos
    Commented Jun 10 at 19:49
  • 1
    Nobody is perfect, you know, ;-) I for sure aint.
    – Hannu
    Commented Jun 10 at 20:54
6

Note: these are a good general solutions to colorize the output of a program. But they don't cope well with interactive shells, as each time you run a command in the interactive shell the prompt and the command will be drawn to the screen only after having hit enter. For use with interactive shells, see @jpa's solution.


Below are two solutions, both similar in concept to Hannu's solution (but using aliases and Perl);

One will colorize the text, the other will colorize both the text and the background;

Both require defining an alias in ~/.bashrc;

I chose white (\e[37m) and red (\e[31m) for the first option and white on dark grey (\e[38;5;15m / \e[48;5;238m) and black on light grey (\e[38;5;0m / \e[48;5;249m) for the second option, but you should probably choose your own colors based on which suit your eyesight the best.

The second option will require more extensive ANSI support from the terminal (it's going to be fine in gnome-terminal and most modern terminals though).

Option #1 (lighter approach): colorize the text

screenshot1

In ~/.bashrc:

alias colorize="perl -pe '\$. %2 ? s/^/\e[37m/ : s/^/\e[31m/; s/\$/\e[0m/'"

Usage:

<command> | colorize

Option #2 (heavier approach): colorize the text and the background

screenshot2

In ~/.bashrc:

alias colorize="perl -pe '
    if( \$. %2) {
        s/^/\e[38;5;15m/; s/^/\e[48;5;238m/
    }
    else {
        s/^/\e[38;5;0m/; s/^/\e[48;5;249m/
    }

    s/\$/\e[K/;
    s/\$/\e[0m/
'"

Usage:

<command> | colorize

The downside to using escape codes to colorize the output is that the output will be polluted with the escape codes; most of the time this won't be an issue, as the main purpose is obviously to run the alias to colorize the output to the terminal, however it's worth noting that, e.g., foo | colorize | tee >file will result in file containing the escape codes.

9
  • 1
    Even more portable, use tput from ncurses-bin - which would at least attempt to actually use $TERM and it's definition. tput setaf 7 ; echo "TEST" ; tput sgr0 ; echo "TEST2" - will imitate your code above. Adding that will of course complicate things again ;-)
    – Hannu
    Commented Jun 10 at 21:05
  • For what it is worth; my code is easier to change ;-) <<-- opinion.
    – Hannu
    Commented Jun 10 at 21:06
  • @Hannu +1 on your comment, which I agree with, however meh, I don't know if I'd like to complicate things with tput considering that, beyond being (rightfully) pedantic, I'd argue (almost) every terminal with color capabilities and their cat will support \e in the end? But besides, it was certainly worth pointing out. Thanks!
    – kos
    Commented Jun 10 at 21:17
  • 1
    @Hannu Ah but your code is fine; I felt like posting this other answer because 1. (main reason) Alias and 2. Shorter / simpler. Easier to change? Probably nah, yours takes the cake :)
    – kos
    Commented Jun 10 at 21:24
  • Thank you so much for your reply! I foolishly realised that I missed a critical detail, I didn't mean the text, but rather the background colour of the Ubuntu terminal, so thank you for reading my mind and including this option! This also works with xspec, however there is an issue where I cannot see my active prompt (i.e. "XSPEC12>") or what I'm typing in the prompt. Once I have hit enter, it shows up, but I can't see it whilst I'm typing
    – Arianna
    Commented Jun 12 at 8:45

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .