6

Steps to reproduce

Consider the following shell command:

echo -e "\e[41mTest\nTest2\e[0mTest3"

It prints Test and in the next line Test2 with a red background (using an ANSI escape code). Test2 is followed directly by Test3 which is uncolored.

Behaviour

The first time this command is executed everything works as expected. However the output is not consistent. After about 10-20 invocations the end of the second line turns red as well. I first stumbled upon this in my C++ App. So I thought it's probably not related to bash.

After the discovery I figured it may be a bug in gnome-terminal. However the behavior is exactly the same in xterm.

Edit

Thanks to the comment of Geno Chen I figured out that this occurs when the terminal runs out of lines and has to scroll.

Screenshots

Here are the screenshots of aforementioned problem:

GNOME Terminal

GNOME Terminal

xterm

xterm

Things in question

Although it makes things a bit unclear in my C++ App it is not a deal breaker. However I'd like to know if there is something wrong with my escape sequences or if this is a bug in some part of the shell. And if there is something I can do to fix it or workaround it.

Community
  • 1
  • 1
Scindix
  • 1,254
  • 2
  • 15
  • 32
  • 2
    I wonder if this take place when the output rolls the window? – Geno Chen Dec 12 '18 at 10:12
  • Yes, it does! Have neither noticed nor thought of that. Thanks for the tip. I added the information to the question. – Scindix Dec 12 '18 at 10:20
  • Works as expected with the WSL shell on windows, even when output rolls the window. – Socowi Dec 12 '18 at 10:21
  • Your question should remain strictly a question. Feel free to submit an answer of your own if you like. – tripleee Dec 12 '18 at 11:09
  • @tripleee But Thomas Dickey basically answered my question so he should get all the reputation. When I post my own answer I feel like possibly stealing from him. – Scindix Dec 12 '18 at 11:12
  • 1
    No, it's fine, especially if you credit his answer for putting you on the right track. *Accepting* your own answer will "rob him" of your current accept, but even that is acceptable if your answer contains significant additional contributions. (At this point, I would not do that, but if you develop your answer further, that day could come.) – tripleee Dec 12 '18 at 11:17

3 Answers3

6

This is for everyone who searches a quick answer. From the links of Thomas Dickey's answer I came up with the following workaround.

echo -e "\e[41mTest\nTest2\e[0mTest3\e[K"

The \e[K part paints the rest of the line with the current background color. As it needs to be sent before every newline character for every line that uses colors I have to rewrite my code a bit though...

tripleee
  • 175,061
  • 34
  • 275
  • 318
Scindix
  • 1,254
  • 2
  • 15
  • 32
5

Filling the line with the currently-selected colors is a detail of bce (back color erase) which could be implemented differently in different terminals—but Linux console and xterm happen to do it this way. It's an FAQ:

Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
  • From the information of your first link I came up with this workaround: `echo -e "\e[41mTest\nTest2\e[0mTest3\e[K"` The `\e[K` paints the rest of the line with the current background color. As it needs to send before every newline character for every line that uses colors I have to rewrite my code a bit though... Thanks for sharing that information. – Scindix Dec 12 '18 at 11:04
0

@Scindix's answer worked great for me, so in order to fix the background colour wrapping, I wrote a tiny script, ./fill-background-colour-to-line-end, that I can pipe another command to:

#!/usr/bin/env ruby
# frozen_string_literal: true

STDIN.each_char do |char|
  print "\e[K" if char == "\n"
  print char
end

Running OP's example and piping it to this, showing it's fixed

Not only does it fix the wrapping weirdness, but filling the background colour to the end of the line was what I'd been wanting anyway =)

Side note: I tried Tilix and LX Terminal; the behaviour there is the same.

ZimbiX
  • 485
  • 3
  • 7