How to Force Set TERM Environment Variable in SSH Config (When Server Overrides It)


6 views

Many developers need to control their terminal environment when SSHing into servers, particularly when working with legacy systems or specific terminal requirements. The default behavior where servers override client-side TERM settings can be frustrating.

The SetEnv directive in SSH config has limitations:

Host server
  Hostname 192.168.x.x
  SetEnv TERM=xterm

This gets ignored because:

  1. Many SSH servers have AcceptEnv restrictions
  2. Remote shells often reset TERM based on their own rules

Option 1: Force Through Remote Command

Host server
  Hostname 192.168.x.x
  RemoteCommand env TERM=xterm bash --login
  RequestTTY force

This approach:

  • Executes your shell with the desired TERM
  • Works even when the server tries to override it
  • Maintains shell login behavior with --login

Option 2: Modify Local SSH Wrapper

Create a wrapper script ~/bin/ssh-term-wrapper:

#!/bin/sh
exec /usr/bin/ssh -t "$@" "TERM=xterm $SHELL"

Then configure SSH:

Host server
  Hostname 192.168.x.x
  ProxyCommand ~/bin/ssh-term-wrapper %h %p

Option 3: Server-Side Forced Setting (When Possible)

If you have limited server access but can modify your own dotfiles:

# Add to ~/.bashrc
[[ -n "$SSH_CONNECTION" ]] && export TERM=xterm

Verify your solution with:

ssh server 'echo $TERM && infocmp'

Key things to check:

  • The output matches your desired TERM
  • Terminal capabilities are correctly reported

If things still don't work:

ssh -v server 2>&1 | grep -i term
# Check server's sshd_config for AcceptEnv
# Verify no conflicting .bashrc/.profile settings

When managing remote servers, many developers encounter an annoying inconsistency: their carefully configured TERM environment variable in ~/.ssh/config gets overwritten. Here's a typical scenario:

# ~/.ssh/config
Host legacy-server
  HostName 192.168.1.100
  SetEnv TERM=vt100  # Trying to force basic terminal emulation

Yet upon connection, echo $TERM shows xterm-256color instead of our configured vt100.

The SSH protocol actually handles terminal environment variables through multiple channels:

  1. Client-side configuration (SetEnv in config or -o SendEnv)
  2. Server-side AcceptEnv settings
  3. Terminal negotiation during SSH connection

The terminal emulation gets negotiated separately from environment variables, which explains why your SetEnv gets ignored.

1. Using RemoteCommand in SSH Config

The most reliable method combines RequestTTY with RemoteCommand:

Host legacy-app-server
  HostName app.example.com
  RequestTTY yes
  RemoteCommand export TERM=vt100; exec bash -l

This approach guarantees the terminal type gets set before your shell starts.

2. TerminalType Directive (OpenSSH 7.7+)

Modern OpenSSH versions support direct terminal specification:

Host color-server
  HostName dev.example.com
  TerminalType xterm-256color

3. ProxyCommand Workaround

For maximum control, chain your connection through a local script:

Host proxied-server
  HostName db.internal
  ProxyCommand /bin/sh -c 'ssh -e none gateway.example.com "TERM=vt100 nc %h %p"'

To understand why your setting isn't working, add verbose output:

ssh -vvv -o SetEnv=TERM=vt100 server.example.com

Look for these key lines in output:

debug1: Sending env TERM = vt100
debug1: Remote: PTY allocation disabled.

Remember that many SSH servers restrict environment variable forwarding. Check /etc/ssh/sshd_config for:

AcceptEnv TERM
PermitUserEnvironment yes

Without these, your client-side TERM settings won't propagate.

When working with legacy industrial systems that only support VT100:

Host plc-controller
  HostName 10.0.0.50
  User operator
  RequestTTY yes
  RemoteCommand export TERM=vt100; stty rows 24 cols 80; exec /bin/sh

This configuration ensures proper terminal emulation and screen dimensions.