【问题标题】:How do programs like man, screen, and vim create temporary overlays?man、screen 和 vim 等程序如何创建临时覆盖?
【发布时间】:2021-06-26 12:00:24
【问题描述】:

几个 *NIX 命令,例如 screenmanvim 等,在 shell 环境中创建临时画布/屏幕/覆盖。当此类程序执行时,它们会覆盖或隐藏之前在终端中显示的任何内容——几乎就像终端窗口中的“全屏”模式一样。然而,当它们终止时,它们会显示或恢复之前在终端上的任何内容。

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

之前

当一个示例全屏程序正在运行时

之后

我希望写入 stdout/stderr 的程序可以完成第一步(用程序特定的内容替换终端的内容),但随后它会产生大量的文本,我可以滚动浏览,因此不能第二步:恢复终端的内容。这意味着程序要么以某种方式记住屏幕的先前内容并重新输出它们(我对此表示怀疑?),要么它在终端中创建某种子窗口,而其他东西则跟踪终端的先前内容.

我的问题

如何在我自己的程序和/或脚本中完成该行为?

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

更新:

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

【问题讨论】:

  • @Rob — 它们都是终端应用程序。不涉及窗口管理器。
  • @Quentin 它看起来像一台 Mac。我打赌他的终端正在那个桌面上运行
  • @Quentin 是正确的。无论操作系统(macOS、Linux)、终端(Terminal.app、iTerm2.app、Putty、Konsole、xTerm 等),甚至是 shell(bash、zsh、csh、tcsh、ksh,甚至是我写的玩具壳)。
  • Man 的来源在这里。随意去看看它的作用:git.savannah.gnu.org/cgit/man-db.git
  • 进入你最喜欢的终端。使用 TERM=xterm-256color 见叠加。改成vt100,没有覆盖......

标签: shell terminal tput


【解决方案1】:

这些程序如何实现这种行为?

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,

这种行为是依赖于 shell 还是依赖于系统?

无,取决于终端模拟器是否支持保存/恢复操作。

【讨论】:

  • 这绝对适用于我的系统,而且看起来它可以在脚本环境中运行。 (当然,ANSI 转义码应该适用于任何现代终端。)MWE 也很棒!但是,我只对tput 很熟悉。如果你能解释一下tput 调用了哪些 ANSI 转义序列,你就会得到答案。
  • smcup 和 rmcup 是转义序列的别名。运行“infocmp screen”查看它们的定义
  • 出于好奇,是否有任何理由想要或需要上述脚本的shebang 中的-
  • @jvriesem 想不出来。只是我盲目遵循的传统
猜你喜欢
  • 2010-10-19
  • 2020-05-16
  • 1970-01-01
  • 2014-08-05
  • 1970-01-01
  • 2015-11-13
  • 1970-01-01
  • 2011-02-03
  • 2021-06-03
相关资源
最近更新 更多