Requesting a PTY in the SSH Protocol

In the SSH protocol, after a client successfully authenticates and opens a session channel, it can send a pty-req (pseudo-terminal request) message to the server.

Requesting a PTY tells the remote server to allocate a virtual terminal interface for the session. It makes the connection act like a real, interactive monitor and keyboard rather than just a raw data pipe.

When the client sends the pty-req, it must provide the server with a few pieces of information:

  1. The Terminal Type string (e.g., "xterm", "vt100").
  2. Terminal dimensions (width and height in characters and pixels).
  3. Encoded terminal modes (special flags like whether local echo is enabled).

The Terminal Type string sets the $TERM environment variable on the server. The server uses this variable to look up the terminal's capabilities in its local database (usually terminfo or termcap). This dictates how programs on the server (like ls, top, or vim) format their output.


What Terminal Types Exist?

Technically, hundreds of terminal types exist. Historically, they corresponded to physical hardware monitors manufactured by different companies. Today, they correspond to software emulators.

Some common families include:

  • Hardware legacy: vt100, vt220 (DEC video terminals).
  • Console/System: linux, console (the raw text interface of an operating system).
  • Modern Emulators: xterm, xterm-256color, rxvt, gnome-terminal.
  • Multiplexers: screen, tmux.
  • Minimalist: dumb.

"xterm" vs. "dumb"

The difference between these two terminal types represents the two extremes of terminal capabilities.

xterm (Highly Capable)

xterm is the standard for modern software terminal emulators. If you tell the server your terminal is xterm (or xterm-256color), you are telling it: "I can handle everything."

  • Capabilities: It supports full-screen cursor addressing (allowing programs like vim or nano to draw user interfaces), text formatting (bold, underline), and advanced color output.
  • Behavior: When running a command like ls or grep, the server will inject ANSI escape sequences (control codes) into the text stream to make files blue, folders green, or errors red.

dumb (Zero Capabilities)

A dumb terminal is exactly what it sounds like: a terminal with almost no capabilities other than sequentially printing text, pressing "Enter", and maybe handling a backspace.

  • Capabilities: It does not support cursor movement, text formatting, or colors.
  • Behavior: When programs on the server see the dumb terminal type, they realize they cannot draw interfaces or use colors. They will fall back to printing plain, unformatted, sequential text. Programs that strictly require drawing a screen (like top or htop) will usually refuse to run, throwing an error like "terminals of type 'dumb' lack cursor addressing."

How to Avoid Terminal Control Codes (ANSI Escape Sequences)

If you are writing a script, using an API (like Chilkat, Paramiko, or libssh2), or automating a task over SSH, you usually want to parse raw text. ANSI escape codes (which look like \033[01;34mFolder\033[0m) will corrupt your string matching and make parsing a nightmare.

Here is how you avoid them:

1. The Best Way: Do NOT request a PTY If you only need to execute a command and capture the output (e.g., ssh user@host "ls -l"), do not send a pty-req at all. By default, if an SSH session does not have a PTY, the server will just stream raw stdout and stderr data. Applications will detect that they are not attached to a terminal and will automatically disable colors and interactive formatting.

2. The Fallback: Request a PTY, but use "dumb" Sometimes, you must request a PTY. For example, some systems require a PTY to execute sudo (to prompt for a password), or you might be interacting with a router/switch CLI that requires a PTY to function. If you must request a PTY but want clean text:

  • Set the terminal type string in the pty-req to "dumb".
  • This ensures the server allocates the pseudo-terminal (satisfying sudo or the router), but instructs all commands to strip out color and cursor control codes before sending the text back to you.

3. Set Environment Variables (If supported) If you are connected and still getting colors from certain stubborn applications, you can try sending the env channel request to set:

  • NO_COLOR=1
  • TERM=dumb (Note: Many SSH servers are configured by default to reject client-provided environment variables for security reasons, so using "dumb" in the actual pty-req is much more reliable).