man、screen 和 vim 等程序如何创建临时覆盖?

How do programs like man, screen, and vim create temporary overlays?

几个 *NIX 命令,例如 screenmanvim 等,在 shell 环境中创建临时 canvas/screen/overlay。当这些程序执行时,它们会覆盖或隐藏之前在终端中显示的任何内容——几乎就像终端 window 中的 "full screen" 模式。然而,当它们终止时,它们会显示或恢复之前在终端上的任何内容。

在下面的示例中,我在屏幕上创建了一些填充文本,然后调用 man bash。手册页打开并覆盖终端显示屏上的所有其他字符。当我关闭手册页时,被遮盖的字符再次显示。

之前

虽然示例 full-screen 程序是 运行

之后

我希望写入 stdout/stderr 的程序可以完成第一步(用 program-specific 内容替换终端的内容),但随后它会产生大量文本,我可以滚动浏览,因此无法执行第二步:恢复终端的内容。这意味着程序要么以某种方式记住屏幕的先前内容并 re-outputs 它们(我对此表示怀疑?),要么它在终端内创建某种 sub-window 并且其他东西会跟踪先前的内容终端的内容。

我的问题

如何在我自己的程序 and/or 脚本中实现该行为?

也许我应该使用 curses/ncurses、tput、termcap/terminfo 或 ANSI 转义序列?

更新:

修改后的问题与https://unix.stackexchange.com/questions/27941/show-output-on-another-screen-and-return-to-normal-when-done基本相同。 (尽管进行了大量搜索,但我在写这个问题时还没有找到它。)不同之处在于我的问题更笼统(任何语言),而那个问题特定于 Bash。两个问题的答案本质上是一样的。如果它与另一个站点上的问题太相似,请随时出于 原因将其关闭。

How do these programs accomplish that behavior?

ANSI 转义序列。尝试 运行 这个脚本:

#/bin/bash -
tput smcup
echo 'Hello world!'
sleep 3
tput rmcup

使用infocmp,您可以看到产生这种叠加效果的底层序列,例如:

$ infocmp -1 | grep 'rmcup\|smcup'
        rmcup=\E[?1049l\E[23;0;0t,
        smcup=\E[?1049h\E[22;0;0t,

is this behavior shell-dependent or system-dependent?

None,取决于终端模拟器是否支持save/restore操作。