0

I'm asking again the question that was asked on StackOverflow with no answers I event added a bounty without an effect (I've just deleted that one). I think that people here may have better knowledge about what is going on.

I'm working on a better ANSI escape code interpreter for my JavaScript library but having a problem with processing the top command (using a script command that dumps terminal output into a file).

I have a sample file from a MacOS that use alternative screen ESC [ ? 1049 h and l as documented here.

The problem is that the Linux version of the top command doesn't use an alternative screen only: \e[H\e[2J sequence which is: goto 1,1 and clear the screen. From my understanding, this should literally wipe everything that was printed on the terminal before that command. This is what I do in my parser/interpreter. But this is not what the Linux terminal is doing (I use an XFce terminal). It somehow clears part of the screen and scrolls down the page.

So my question is what are the exact steps (algorithm) to process the top command (\e[H\e[2J sequence) to render it like on a Linux terminal? I need to have a single string as the output of the session as it looks on my terminal.

Here is a sample output of the script command: https://jcubic.pl/screen_dump_linux_top.txt

I have testing code on CodePen:

that use this code:

$.terminal.format($.terminal.overtyping($.terminal.from_ansi(text)));

if you look at the output of the top command on Linux. You will see that there is no output before the command. In comparison to the macOS file that prints everything (I know that the real terminal doesn't print an alternative screen when switching back to the primary screen, but I decided that I want that output there, maybe I add an option to toggle that).

I know that I can just check the terminal emulator source code, but it will probably take a lot more time, than just asking this.

1
  • I'm wondering what is wrong with my question to get a downvote. On StackOverflow when I first asked this I've got two upvotes but no reply. It seems that this is a better place to ask questions like this.
    – jcubic
    Nov 9, 2022 at 10:05

3 Answers 3

1

\e[H moves the cursor home (top left corner) and \e[2J clears the screen (the regularly viewed part, but not the scrollback).

In many terminal emulators \e[2J simply clears the regularly viewed part of the screen in-place. The result is: if you execute a command that produces some output (e.g. seq 100 for testing purposes) and then execute top then the beginning of the previous program's output is preserved in the scrollback buffer but the end of its output is lost forever.

To workaround this illogical behavior, some terminal emulators (including the VTE widget used by your Xfce Terminal) modify the behavior of \e[2J: it scrolls the screen out into the scrollback buffer. The result in the "regular area" is the same: you get an empty screen. The scrollback buffer's contents arguably make more sense: the entire output of the previous command is preserved.

You can use \e[3J to clear the scrollback buffer, if that's what you want to do. Emit this after \e[2J, otherwise one screenful of data will be scrolled out there. (This is what the clear command does.)

So my question is what are the exact steps (algorithm) to process the top command (\e[H\e[2J sequence) to render it like on a Linux terminal?

The answer is: it depends on which terminal.

1
  • Thanks, it's really helpful.
    – jcubic
    Nov 9, 2023 at 22:25
0

But this is not what the Linux terminal is doing (I use an XFce terminal). It somehow clears part of the screen and scrolls down the page.

Actually, echo -e "\033[H\033[2J" does exactly what you expected - go to a top-left, clear the rest of the screen buffer.

The scroll down you see comes from the fact that your screen buffer has more rows than your terminal does.

Do stty size to see how many rows and columns you have. Do stty rows X cols Y to change it.

2
  • I don't think that it does what I think it does. When I call clear && command cat screen_dump_linux_top.txt it doesn't clear the beginning of the content only creates blank lines after I've typed top. If I scroll the terminal to the top I don't see the top command output only black space.
    – jcubic
    Nov 9, 2022 at 9:58
  • I agree that when I have more content on the terminal emulator it looks like it does what I expect but not so much on a clear terminal. jcubic.pl/terminal-clear.gif
    – jcubic
    Nov 9, 2022 at 10:12
0

I think I've figured this out on my own. I was not able to find any information about ANSI escapes codes in the XFce Terminal source code. I'm not sure where ANSI code is handled.

But the solution was this algorithm:

  1. When there is an [H code save the cursor position.
  2. When there is an [2J code and the previous code was H restore the cursor position.
  3. Forward one line and move x to 0.
  4. Save y position as scroll_top.
  5. Now every time you have an [x;yH or [H code use scroll_top as the offset for the y cursor position.

This works even better than the Linux terminal since it clears that many lines so the next line is at the top of the screen. and iTerm2 on macOS works similarly to my algorithm but it only scrolls the window so the 1 1 position is at the top left of the terminal window.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .