Ctrl+L vs clear

In a terminal, you can clear the screen in two common ways:

  • Run the clear command
  • Press Ctrl+L

The result looks the same at first, but there’s a catch: clear can also wipe your scrollback buffer1, while Ctrl+L never does. Also, behind the scenes they’re implemented in different ways.


Ctrl+L

When you press Ctrl+L at the Bash prompt, it’s not invoking an external program, but instead it’s handled inside GNU Readline, the library Bash uses for interactive line editing2. In Readline’s input keymap, the key Ctrl+L is bound to the clear-screen function. You can confirm this with:

bind -P | grep clear-screen

which shows:

clear-screen can be found on "\C-l".

The function name “clear-screen” is registered in funmap.c:

{ "clear-screen", rl_clear_screen },

The actual function rl_clear_screen() is defined in text.c. It calls the helper function _rl_clear_screen(), defined in display.c, which eventually calls:

tputs(_rl_term_clrpag, 1, _rl_output_character_function);

Here _rl_term_clrpag is a global char * set up in terminal.c. At startup, Readline queries terminfo(5)3, and assigns to _rl_term_clrpag the value of the “clear” capability (short code “cl”)4. On a terminal with $TERM set to xterm-256color, that expands to:

\E[H\E[2J

which means:

  • ESC[H → move the cursor to the home position (row 1, column 1)
  • ESC[2J → erase the entire screen

You can see this mapping yourself with:

infocmp -C $TERM | grep 'cl='

So Ctrl+L sends ESC[H ESC[2J, clears the visible screen, and redraws the prompt, but scrollback remains intact.


clear(1)

When you run the clear(1) command, you’re executing a program provided by ncurses. Like Ctrl+L, it looks up the “clear” capability in terminfo(5) and prints the corresponding escape sequence. But clear goes a step further: unless you pass -x, it also checks for the extended capability E3, which on xterm is defined as:

E3=\E[3J

which tells the terminal to erase the scrollback buffer. That’s the key difference.

Here’s the relevant code from clear.c, which calls clear_cmd.c:

int
clear_cmd(bool legacy)
{
    int retval = tputs(clear_screen, lines > 0 ? lines : 1, putch);
    if (!legacy) {
	/* Clear the scrollback buffer if possible. */
	char *E3 = tigetstr("E3");
	if (E3)
	    (void) tputs(E3, lines > 0 ? lines : 1, putch);
    }
    return retval;
}

where:

  • clear_screen is a macro defined in term.h, and after setupterm() initializes the terminal entry, it expands to the string for the “clear” capability ( on xterm-256color that’s \E[H\E[2J).
  • The second part (tigetstr("E3")) is what makes clear different from Ctrl+L: if defined, it sends \E[3J to erase scrollback.

So on an xterm-like terminal:

  • clear = ESC[H ESC[2J ESC[3J → clears screen and scrollback
  • clear -x = ESC[H ESC[2J → same as Ctrl+L

You can try it directly:

echo -e "\033[H\033[2J"        # clear only (Ctrl+L / clear -x)
echo -e "\033[H\033[2J\033[3J" # clear + erase scrollback (clear)

In short, Ctrl+L and clear -x both just reset the visible screen, while plain clear also erases the scrollback.



  1. This depends on the terminal. On xterm-like terminals, clear uses the extra terminfo capability E3 (\E[3J) to erase scrollback. On terminals without E3, it behaves the same as Ctrl+L. ↩︎

  2. When you type commands at the prompt, readline(3) is what gives you things like line editing (Ctrl+A to move to start, Ctrl+E to move to end), command history (arrow keys to scroll through previous commands) etc. ↩︎

  3. It’s a database that describes what escape sequences a terminal understands in terms of named capabilities. ↩︎

  4. Terminfo long names (like clear_screen) and termcap short names (like cl) are equivalent; you can see them with infocmp -L and infocmp -C↩︎