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:
- Many SSH servers have
AcceptEnv
restrictions - 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:
- Client-side configuration (
SetEnv
in config or-o SendEnv
) - Server-side AcceptEnv settings
- 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.