在bash脚本中使用“替代屏幕”

65

备用屏幕被许多类似vim、htop、screen、alsamixer和less等“用户交互”终端应用程序使用。它就像终端内容的另一个缓冲区,在应用程序退出时消失,因此整个终端会被恢复,看起来好像应用程序没有输出任何东西。

我想在自己的Shell(bash)脚本中实现完全相同的功能,但它不必那么便携。我将仅限于Linux和基于xterm的终端仿真器;但如果可能的话,解决方案应使用类似tput的东西。然而,我不想使用一些外部脚本语言(甚至是C之类的东西)。

尽管我不想使用C(因为它应该是一个尽可能少依赖的bash脚本),但我查看了less的源代码。它似乎将terminfo作为数据库,并在初始化时查找“ti”终端能力。当删除该行时,它不使用备用屏幕,因此我认为我找到了负责的代码行。

但是,我在man terminfo中找不到这样的能力。但也许我正在错误的路径上寻找解决方案。也许terminfo / tput不是我的好朋友。

那么,我如何在bash脚本中使用备用屏幕呢?是否有人知道一个简单的应用程序,在其中可以找到提示的源代码?(C应用程序或bash脚本或其他...)

3个回答

91

你可以使用以下命令切换到备用屏幕:

$ tput smcup

并且回来:

$ tput rmcup

这些命令只是输出适合您终端的转义序列。如果是XTERM,它们将等同于(更为人所知但不够优雅或便携的):

$ echo -e "\e[?1049h"

并且:

$ echo -e "\e[?1049l"

要查看更多终端控制命令,请参阅man 5 terminfo


@leemes - 实际上,重新阅读您的问题,您谈到了“ti”终端能力...但是如果您仔细查看“man terminfo”,它只是“smcup”的termcap名称!!! - rodrigo
我能发誓我搜索了ti(如问题中所提到的),但没有找到这个功能!该死...-.- - leemes
3
在我的系统上,如果我没有指定部分,我会得到 terminfo(3ncurses),所以我使用 man 5 terminfo 来获取适当的文档。(供那些可能不知道的人参考) - Dennis Williamson
2
@caffinatedmonkey,ECMA-48:http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-048.pdf - Eric Smith
1
@blalor 我已经因为同样的原因来过几次了。我需要弄清楚是否可以编写一个小函数来“捕获”从SSH/screen退出并运行rmcup以返回正确模式。缺点是当它切换时,我会失去在缓冲区中存在的SSH/screen输出,因为终端被“重置”为正常屏幕而不是备用屏幕。 - dragon788
显示剩余3条评论

9

smcup/rmcup被使用,但仅用于副作用:在这些terminfo功能中通常嵌入了在常规/交替屏幕之间切换的转义序列 - 不总是。

xterm faq中有一些背景资料:运行vi时为什么屏幕没有清除?


5

针对 C 控制台应用程序:

ncurses

维基百科:

ncurses(new curses)是一个编程库,提供了 API,允许程序员以不受终端限制的方式编写基于文本的用户界面。

less 使用了这个库。

这里可以找到一个 hello world 程序,在 GCC 中编译它需要使用 -lncurses 标志。

#include <ncurses.h>

int main()
{   
    initscr();          /* Start curses mode          */
    printw("Hello World !!!");  /* Print Hello World          */
    refresh();          /* Print it on to the real screen */
    getch();            /* Wait for user input */
    endwin();           /* End curses mode        */

    return 0;
}

构建步骤:

$ gcc hello-world-ncurses.c -lncurses

8
然而,我不想使用任何外部脚本语言(甚至类似于C的东西)。 - n. m.
也许这个答案与OP的问题不太相关,但它真的很酷 :) 另外请注意:flag -lncurses 的意思是这样做:$ gcc hello-world-ncurses.c -lncurses - user5395338

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接