Цвет фона терминала не всегда корректно сбрасывается с помощью "\ 033 [0m" - PullRequest
2 голосов
/ 10 октября 2019

Попытка понять поведение терминала, когда дело доходит до сброса цвета фона в Unix-подобных ОС (Mac, Linux).

Рассмотрим сценарий bash

#!/usr/bin/env bash

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

При первом запускеВ этом сценарии все как и ожидалось. Однако, если я повторю это несколько раз, результат печати изменится. Следующая строка "Back to Normal" представляет собой строку с голубым фоновым цветом.

Снимок экрана (терминал, Mac OS Mojave):

enter image description here

Вопросы:

  1. Почему это? Кто-нибудь может объяснить это поведение?
  2. Если я изменил цвет фона и распечатал строку (заканчивающуюся новой строкой) , что я могу сделать, чтобы правильно сбросить фон и избежать этого нежелательногоконечный цвет фона?

Для вашей информации, я проверил это поведение на терминале Mojave Mac OS и на терминале Ubuntu 18.04. И я проверил, используя эквивалентный скрипт Python 3. Результаты соответствуют. Я также пытался использовать fflush(stdout) в C / C ++, но напрасно.

PS Этот вопрос связан с программой C ++, которая будет работать на Mac или Linux. Я думал, что это не имеет отношения к самому языку, поэтому я упростил его до сценария bash. Если возможно, предложите решение, которое может быть сделано на C / C ++.

1 Ответ

3 голосов
/ 10 октября 2019

Ваша проблема вызвана прокруткой терминала.

Когда ваш голубой "On Cyan" фон выдает новую строку, которая вызывает прокрутку терминала, фон вставленной пустой строки заполняется текущим известным фоном: cyan.

Затем вы сбрасываете атрибут цвета, и ваш текст «Назад к нормальному» печатается с фоном по умолчанию, но область строки, которая не была перезаписана, по-прежнему является голубой.

Вы должны сбросить атрибуты до достижения конца строки следующим образом:

#!/usr/bin/env sh

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

В качестве альтернативы вы можете выполнить очистку до конца строки tput el или printf "\033[K" после сброса текстовых атрибутов:

#!/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"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...