终端背景颜色并不总是使用“\033[0m”正确重置

aaf*_*lei 5 c unix macos bash terminal

尝试了解在类 Unix 操作系统(Mac、Linux)上重置背景颜色时的终端行为。

考虑一个 bash 脚本

#!/usr/bin/env bash

printf "\033[46m"
printf "On Cyan\n"
printf "\033[0m"
printf "Back to Normal\n"
Run Code Online (Sandbox Code Playgroud)

当我最初运行这个脚本时,一切都按预期进行。但是,如果重复几次,打印结果就会改变。以下"Back to Normal"是青色背景色上的一条线。

屏幕截图(终端,Mac OS Mojave):

在此输入图像描述

问题:

  1. 为什么是这样?谁能解释这种行为?
  2. 如果我更改了背景颜色并打印了一行(以换行符结尾),我该如何正确重置背景并避免这种不需​​要的尾随背景颜色?

供您参考,我已在 Mac OS Mojave 终端和 Ubuntu 18.04 终端上测试了此行为。我已经使用等效的 Python 3 脚本进行了测试。结果是一致的。我也尝试过fflush(stdout)在 C/C++ 中使用,但没有成功。

PS 这个问题源于要在 Mac 或 Linux 上运行的 C++ 程序。我认为这与语言本身无关,所以我将其简化为 bash 脚本。如果可能,请建议一个可以用 C/C++ 完成的解决方案。

Léa*_*ris 6

您的问题是由终端滚动引起的。

当您的“On Cyan”青色背景发出导致终端滚动的换行符时,插入的空白行的背景将填充当前已知的背景:青色。

然后,您重置颜色属性,并且“返回正常”文本将使用默认背景打印,但未被覆盖的线条区域仍为青色。

您应该在到达行尾之前重置属性,如下所示:

#!/usr/bin/env sh

printf "\033[46m"
printf "On Cyan"
printf "\033[0m"
printf "\nBack to Normal\n"
Run Code Online (Sandbox Code Playgroud)

或者,您可以在重置文本属性后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"
Run Code Online (Sandbox Code Playgroud)