aafulei
aafulei

Reputation: 2205

Terminal background color not always properly reset using "\033[0m"

Trying to understand terminal behavior when it comes to reset background color on a Unix-like OS (Mac, Linux).

Consider a bash script

#!/usr/bin/env bash

printf "\033[46m"
printf "On Cyan\n"
printf "\033[0m"
printf "Back to Normal\n"

When I initially run this script, everything is as expected. However, if I repeat it for several times, the printing result changes. Following "Back to Normal" is a line on cyan background color.

The screenshot (Terminal, Mac OS Mojave):

enter image description here

Questions:

  1. Why is this? Can anyone explain this behavior?
  2. If I have changed background color and have printed out a line (ending with newline), what can I do to properly reset the background and to avoid this unwanted trailing background color?

For your information, I have tested this behavior on Mac OS Mojave Terminal, and on Ubuntu 18.04 Terminal. And I have tested using an equivalent Python 3 script. Results are consistent. I also tried using fflush(stdout) in C/C++ but in vain.

P.S. This question stems from a C++ program to be run on Mac or Linux. I thought it is irrelevant to the language itself, so I simplified it down to a bash script. If possible, please suggest a solution that can be done in C/C++.

Upvotes: 5

Views: 2073

Answers (1)

Léa Gris
Léa Gris

Reputation: 19545

Your issue is caused by the terminal scrolling.

When your "On Cyan" cyan background issue a newline that causes the terminal to scroll, the background of the inserted blank line is filled with the current known background: cyan.

Then you reset the color attribute and your "Back to normal" text prints with the default background, but the area of the line that has not been overwritten, is still cyan.

You should reset the attributes before reaching the end of the line like this:

#!/usr/bin/env sh

printf "\033[46m"
printf "On Cyan"
printf "\033[0m"
printf "\nBack to Normal\n"

Alternatively you could issue a clear to end of line tput el or printf "\033[K" after resetting the text attributes:

#!/usr/bin/env sh

printf "\033[46m" # same as tput setab 6
printf "On Cyan\n"
printf "\033[0m\033[K" # same as tput -S <<<$'sgr0\nel'
printf "Back to Normal\n"

Upvotes: 6

Related Questions