62

The alternate screen is used by many "user-interactive" terminal applications like vim, htop, screen, alsamixer, less, ... It is like a different buffer of the terminal content, which disappears when the application exits, so the whole terminal gets restored and it looks like the application hasn't output anything.

I'd like to achieve exactly the same thing in my own shell (bash) script, except that it doesn't have to be that portable. I'd stick to linux only and xterm-based terminal emulators; but the solution should use something like tput if it's possible. However, I don't want to use some external scripting language (or even something like C).

Although I don't want to use C (as it should be a bash-script with as few dependencies as possible), I had a look into the source code of less. It seems to use terminfo as the database and looks up the "ti" terminal capability in its initialisation. When removing the line, it doesn't use the alternate sceen, so I assumed that I found the responsible code line.

However, I can't find such a capability in man terminfo. But maybe I'm on the wrong path finding a solution for this. Maybe terminfo / tput isn't my friend.

So (how) can I use the alternate screen in a bash script? Does somebody know a simple application in which source code I may find a hint? (C application or bash script or whatever...)

leemes
  • 44,967
  • 21
  • 135
  • 183

3 Answers3

89

You can switch to the alternate screen using this command:

$ tput smcup

And back with:

$ tput rmcup

These commands just output the appropriate escape sequences for your terminal. If it is an XTERM they will be equivalent to the (more known but less elegant or portable):

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

And:

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

For more terminal control commands see man 5 terminfo.

rodrigo
  • 94,151
  • 12
  • 143
  • 190
  • @leemes - Actually, re-reading your question, you talk of the `ti` terminal capability... but if you look carefully in `man terminfo`, it is just the termcap name of `smcup`!!! – rodrigo Jun 13 '12 at 22:35
  • Lol? I could *swear* that I searched for `ti` (as mentioned in the question) and didn't find the capability! Damn... -.- – leemes Jun 13 '12 at 22:37
  • 3
    On my system, if I don't specify the section, I get `terminfo(3ncurses)`, so I use `man 5 terminfo` to get the appropriate document. (posted for those who may not be aware of it) – Dennis Williamson Jun 14 '12 at 00:35
  • What standard are these escape sequences part of? ANSI? VT200? – 0xcaff Jul 04 '14 at 23:24
  • 2
    @caffinatedmonkey, ECMA-48: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-048.pdf – Eric Smith Apr 13 '16 at 11:06
  • Thank you, thank you, thank you. This helped me figure out a problem I've had for years, where sometimes after an ssh connection gets dropped the mouse wheel scrolls the readline history instead of the scrollback buffer. Alternate screen mode was left enabled, so turning it off was all it took! W00t! – blalor May 05 '17 at 10:42
  • 1
    @blalor I've been here a few times for the exact same reason. I need to figure out if I can write a small function to "trap" on exit from SSH/screen and run `rmcup` to get back into the correct mode. The downside is when it switches I lose the SSH/screen output that was present in the buffer from just prior to my session exiting due to the "reset" of the terminal to the normal screen vs the alternate screen. – dragon788 Jan 29 '18 at 17:14
9

smcup/rmcup are used, but only for the side effect: the escape sequence which switches between normal/alternate screens is usually embedded in those terminfo capabilities -- not always.

Some background is in the xterm faq Why doesn't the screen clear when running vi?

Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
5

For C console application:

ncurses

Wikipedia:

ncurses (new curses) is a programming library that provides an API which allows the programmer to write text-based user interfaces in a terminal-independent manner.

less uses this library.

A hello world program from here, to compile it in gcc, flag -lncurses is needed.

#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;
}

To build:

$ gcc hello-world-ncurses.c -lncurses
golopot
  • 10,726
  • 6
  • 37
  • 51
  • 8
    **However, I don't want to use some external scripting language (or even something like C).** – n. m. could be an AI Nov 02 '14 at 10:36
  • Perhaps this answer is not iaw the OP's question, but it's really cool :) **NOTE ALSO:** The `flag -lncurses` means do this: `$ gcc hello-world-ncurses.c -lncurses` –  May 19 '22 at 14:48