终端 "ASCII animation" 是如何工作的?

How does a terminal "ASCII animation" work?

我称它为 ASCII 动画,找不到更好的词了。我指的是例如加载栏,比如 pacman(arch 包管理器),它是这样开始的...

[          ]

并把时间翻到这个...

[####      ]

根据我对 stdout 的理解,我似乎无法理解这个看似简单的 feature.I 期望...

[          ]
[#         ]
[###       ]
...

我不明白的是它如何能够在 stdout 之上打印,(如果它正在这样做的话)。

我们有时认为终端只是显示文本,但实际上它们更像浏览器,以控制字符和 ANSI 终端转义码的形式呈现自己的小标记。

简单的单行动画通常使用马车 Return 控制字符来完成。通过写回车 return,光标 returns 到最左边,因此您可以根据需要在该行上重复写多次。

您显然会使用循环,但为了清楚起见,这里写了一个示例:

{
  printf '[##    ]'
  sleep 1
  printf '\r[###   ]'
  sleep 1
  printf '\r[####  ]'
}

对于更高级的动画,您可以例如通过将特殊的 ANSI 转义序列写入文本来任意定位光标。 tput 工具在 shell 脚本中对此很有帮助,并且 tput cup 4 50 将输出一个 ANSI 序列以将光标移动到第 4 行第 50 列。这相当于 printf '\x1B[4;50H' 和只是向终端写入一段魔法文本。

这是用于星空动画的功能(ctrl-c 退出):

while sleep 0.1
do
  tput cup $((RANDOM%LINES)) $((RANDOM%COLUMNS))
  printf "*"
done

甚至像 topnano 这样的工具也会通过仔细编写文本和控制字符来创建颜色、线条、刷新列表等来显示它们所显示的内容。