Skip to main content

Command Palette

Search for a command to run...

Why does my terminal get cleared every time I exit ssh?

Updated
4 min readView as Markdown
K

I am a web developer focusing on building web application using Python and Django. Full profile on https://kamal.koditi.my/.

When I exit from a session, my local terminal
just went blank - not just the visible screen, the entire scrollback was gone too. Annoying to the point where I wanted to know exactly
what happened.

Some upfront notes - the machine I was connecting to runs AlmaLinux 9 with zsh as the login shell. My local machine was running fish, but
it turned out to be irrelevant.

The Symptoms

Every time I do an interactive ssh session and exit, it looks like this:-

  kamal@server:~$ exit                                                                                                                     
  Connection to 267.100.278.345 closed.                                                                                                    
                                                                                                                                           

And that's it. The screen is blank, and I can no longer scroll up to see what I did a moment ago.

The usual suspects first - ~/.bashrc, ~/.bash_logout, ~/.zshrc - none of them have anything to do with clear. Nothing. So what's clearing
the screen?

Reading The Escape Sequences

The terminal only clears if someone sends it an escape sequence. So let's catch the session with its hands dirty. I feed it a script to
just run exit and capture everything the remote sends, rendered as visible characters:-

  printf 'exit\n' | ssh -tt -l kamal 200.100.200.100 2>/dev/null | cat -v | tail -c 300                                                    

And there it is, the last thing the remote wrote before hanging up:-

  ^[[H^[[2J^[[3J                                                                                                                           

That's cursor home, clear screen, clear scrollback. So the bytes come out of the remote shell on exit - not my local fish, not the
terminal emulator, not oh-my-zsh. The remaining work is just finding who sent them.

The Red Herring

The output also had some terminal-title escapes right before the clear, and the remote has oh-my-zsh, which has auto-title hooks.
Suspicious. So I disabled the title with DISABLE_AUTO_TITLE="true" and tested again.

It didn't help. The screen was still cleared. Turns out those title escapes were just a neighbor in the byte stream. Good thing for me I
actually captured the stream instead of guessing, otherwise I would have shipped a "fix" that does nothing.

Isolating It

I kept bisecting with the same capture command. The pattern that stood out was this:-

  • zsh (non-login) inside the session, then exit -> not cleared

  • zsh -l (login) with a completely empty config, then exit -> cleared

  • bash -l, then exit -> not cleared

An empty config that still gets cleared means nothing in ~/.zshrc or oh-my-zsh is responsible. This is the shell package itself. And
login-only, because sshd always starts the session shell in login mode.

The Culprit

AlmaLinux's zsh package ships a file that I never once looked at because it doesn't even live under /etc/zsh/ - just /etc/zlogout:-

  #                                                                                                                                        
  # /etc/zlogout and ~/.zlogout are run when an interactive session ends                                                                   
  #                                                                                                                                        
  clear                                                                                                                                    

That's the whole file. It is run when an interactive login session ends, and it runs clear. Since it also clears the scrollback,
everything I typed during the session is gone. On Debian-based distros the same file lives under /etc/zsh/ and this behavior is well-known

  • the RHEL family just hides it in a less obvious place.

The Fix

Creating ~/.zlogout does not override it - zsh reads both, user first, then system. The documented trick is to tell zsh to stop reading rc files after this point:-

  echo 'setopt norcs' > ~/.zlogout                                                                                                         

norcs means "do not read the next rc file", which at this point of the shutdown is exactly /etc/zlogout and nothing else. After adding
that, the same capture command shows a normal exit with none of the escape sequences. Testing my real flow - ssh in, do some work, exit -
the scrollback survives now.

If you have root and want to fix it for everyone on that box, just truncate or remove the clear line in /etc/zlogout itself.

2 views