How do commands like top update output without appending in the console?

Solution 1:

There are, potentially, two mechanisms at work here.

One is use of ANSI escape codes (and other non-ANSI codes in some cases), as mentioned by Martin Prikryl in their answer, to implement a text-based pseudographical interface. The bare minimum for this is exactly two specific ANSI escape codes, ^[[2J, which erases everything on the screen, and ^[[;H, which moves the cursor to the top left of the screen. By combining those, you can write out the contents of each ‘frame’ one by one without adding to the scrollback buffer. Most applications actually use a lot more than just those (for example, there are a set of codes for moving the cursor in arbitrary directions, and it’s pretty normal to use these to skip over parts of the screen that should be ‘empty’). In practice, most (but by no means all) larger applications utilize either libcurses (or more often, ncurses) or a direct equivalent to handle all of this for them.

The other possibility, which is usually combined with the use of ANSI escape codes to manipulate the screen contents, is a special feature originally provided by xterm, but now widely implemented by most decent terminal emulators, called the alternate screen buffer. There are a pair of escape codes (^[[?1049h and ^[[1049l) used to switch between this and the regular scrollback buffer. By switching to the alternate screen buffer before presenting a textual UI, programs can completely avoid altering the scrollback buffer at all, which not only prevents you from scrolling without having to intercept the keystrokes that would normally scroll, it also lets the program do things like let you inspect the existing terminal contents from before the program was run (and makes it easier to see what you were doing before you opened that full-screen application).

Solution 2:

What you observe is the product of a historical development.

The earliest interactive terminals were true-to-god teletypewriters; essentially electric typewriters connected to a telephone line. (Ever wondered why /dev/tty is named the way it is named?) You could type a text command (with, iirc, even some basic, awkward line editing) and would get a text output.

Those, of course, could only move left-to right and top-down. Oh wait, not true! They could go back a char with Ctrl-H and type it again, making it bold. Behold, that's what some programs still do that format text for printers. Teletypewriters also had a few basic control codes like line feed, form feed or a bell.

The step to a CRT based terminal was logical, if only to save the trees. But ever since, each and every terminal (emulator) has provided the basic functioning of a teletypewriter: Unless told otherwise (with the famous escape sequences), received 7 bit ASCII codes, including the basic control codes, are interpreted as the corresponding characters or commands and displayed left-to-right, top-to-bottom, starting at the current cursor position which was maintained by the terminal.

But since the smarter terminals were actually able to display characters at arbitrary line/column positions on the screen they all had some means to do that programmatically, through control code sequences, and the operating systems were one way or another configured to use the proper sequences. Some programs, notably editors, shells and other interactive, user oriented programs like top use this capability to control the entire screen.

The reason this "visual mode" is not more common is that simply outputting a linear sequence of characters without "decoration" is enormously versatile — and at the same time sufficient for a wide range of outputs: You can print tabulated data which is still essentially a serial sequence of characters with whitespace (space, tab, newline). The entire Unix/Linux ecosystem with pipes and devices is built around this paradigm. It allows you to plug "building bricks" like find, grep, cut etc. together and process textual information automatically. That would be entirely impossible if the output were mixed with positioning and formatting commands.