Scindix
Scindix

Reputation: 1294

ANSI escape code weird behavior at end of line

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.

Upvotes: 7

Views: 2306

Answers (3)

ZimbiX
ZimbiX

Reputation: 495

@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.

Upvotes: 0

Scindix
Scindix

Reputation: 1294

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...

Upvotes: 6

Thomas Dickey
Thomas Dickey

Reputation: 54515

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:

Upvotes: 5

Related Questions