【问题标题】:Terminal background color not always properly reset using "\033[0m"终端背景颜色并不总是使用“\033[0m”正确重置
【发布时间】:2020-02-07 10:11:31
【问题描述】:

尝试了解在类 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):

问题:

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

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

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

【问题讨论】:

  • 修复:tput sgr0;不过,不太清楚为什么会发生这种情况。
  • @BenjaminW。谢谢。在运行脚本之前尝试了tput sgr0。但是,不起作用。问题仍然存在。
  • 确切地说,我尝试在printf "\033[0m" 之前和之后插入tput sgr0。但是,和以前一样,在重复脚本大约 10 次之后,问题又回来了。
  • 我在 bash 终端上运行相同的脚本,但无法重现您的问题。
  • @PrateekJoshi 嗨。此问题通常在您快速重复大约 5-10 次后出现。您是否快速重复(例如使用向上箭头键 + 回车)并且重复了足够多的时间?

标签: c bash macos unix terminal


【解决方案1】:

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

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

然后您重置颜色属性,您的“恢复正常”文本以默认背景打印,但未被覆盖的行区域仍然是青色。

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

#!/usr/bin/env sh

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

或者,您可以在重置文本属性后发出清除行尾tput elprintf "\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"

【讨论】:

  • 感谢您回答第一个问题。我不知道是因为终端滚动。现在很有意义!我还注意到,如果我这样做 printf "\033[46mOn Cyan\033[0m\n" 不会有问题。那么这样是不是意味着我的第二个问题(如果我发出换行符如何重置)没有可行的解决方案?
  • 这就是您应该始终在换行之前或达到当前终端宽度或达到最后一列之前重置属性的原因。使用tput cols查询终端宽度,tput lines查询终端高度;这样您就可以控制文本流并避免在滚动时将属性泄漏到插入的行中。
  • 谢谢!坦率地说,我不熟悉tput。是否有可能在 C 中实现这种效果(通过包括标准库或所有类 Unix 操作系统上提供的库,如 Windows 上的 &lt;windows.h&gt; 标头)?
  • 在 C 或 C++ 中,使用 #include &lt;ncurses.h&gt; 和它的方法来做同样的事情,甚至比 tput 命令更高级的东西。
  • @LéaGris 查找终端信息的旧库是&lt;termcap.h&gt;,它的功能嵌入在一个库中,旨在使基于屏幕的定位更容易,称为&lt;curses.h&gt;,该库已发布更新版本;因此&lt;ncurses.h&gt;。这种沿袭意味着有时您可以使用一个库的文档来理解另一个库的调用,尽管它并不总是完美的。您想要的(对于宽度)是 termcap 数据库中的 co 键,gnu.org/software/termutils/manual/termcap-1.3/html_mono/… 很好地涵盖了终端命令。
猜你喜欢
  • 2016-12-18
  • 1970-01-01
  • 2023-03-18
  • 2010-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多