bashshellterminalless-unix

How does terminal programs add scrolling to the screen?


How does the programs less, more, or vi add a scrolling section on the terminal screen without clearing the screen and how does it disappear afterwards?

Is there any way to run less for a specific amount of time if I was running it from a script or a way for the script to exit?


Solution

  • First off, this has nothing to do with bash or whatever shell you're using. The less command itself handles its screen updates; it can be run from any shell, or from any other program.

    Your terminal emulator supports escape sequences. Writing printable characters (letters, digits, etc.) causes those characters to be displayed. Writing escape sequences causes various other things to happen: moving the cursor, clearing the current line, clearing the screen, etc.

    The termcap or terminfo and curses or ncurses software packages provide access to these escape sequences. less, vim, emacs, typically use ncurses to help manage the screen.

    Two sequences relevant to your question are called ti and te by termcap, smcup and rmcup by terminfo. The smcup sequence causes the terminal to save its current state (everything displayed on the screen as well as the cursor position), then switches to a secondary display buffer that starts off empty. The rmcup sequence restores the saved state and goes back to the primary display buffer. Programs that use ncurses will, by default, print the smcup sequence on entry and the rmcup entry on exit. That's how such programs are able to restore your terminal window to its previous state when they terminate.

    Also is there any way to run less for a specific amount of time if i was running it from a script or a way for the script to exit

    I don't think there's a really good way to do that. less is an interactive program; it normally terminates only when the user types q or something similar. Running it for a specific amount of time goes against what it's designed to do, and as a user I'd be annoyed if less were terminated while I'm using it.

    You could use the timeout command, but that interferes with the smcup / rmcup mechanism, leaving you with a possibly corrupted display. There's probably a better way to accomplish what you're trying to do.