Fixing SSH Terminal Character Corruption in Vim/Nano on Remote Linux Servers


2 views

For months, I've been battling a frustrating issue when editing files on remote CentOS servers (versions 5.5, 5.7, and 6) via SSH from my Mac (OS X Lion). The problem manifests when using either vim or nano - the cursor jumps unpredictably during editing, causing text corruption like this:

Original intended text: "This is a line of text."
Actual saved result: "This is a neof text."

After extensive testing, I've identified this as a terminal emulation issue. The problem stems from mismatched TERM environment variables between the local and remote systems, combined with incomplete terminfo databases on the older CentOS servers.

Here are the working fixes I've implemented:

# Solution 1: Force xterm-256color on the remote server
$ ssh -t username@example.com "export TERM=xterm-256color; bash"

Alternatively, add this to your ~/.bashrc on the remote server:

# Solution 2: Permanent TERM fix
if [ -n "$SSH_CONNECTION" ]; then
    export TERM=xterm-256color
fi

For servers where you don't have root access to update terminfo:

# Solution 3: Local terminfo override
$ mkdir -p ~/.terminfo/x
$ infocmp xterm-256color > /tmp/xterm-256color.terminfo
$ scp /tmp/xterm-256color.terminfo user@example.com:~/.terminfo/x/

Verify your terminal is properly configured with:

$ tput colors
256
$ infocmp | grep -E 'khome|kend'
        khome=\E[H, kend=\E[F,

If you see proper key definitions and 256 colors, your terminal should now behave correctly in both vim and nano.

If issues persist, consider using SSHFS to mount the remote filesystem locally:

# Install SSHFS on Mac
$ brew install sshfs
$ mkdir ~/remote_server
$ sshfs user@example.com:/path/to/files ~/remote_server

Then edit files using your local editor of choice.


For months now, I've been battling a frustrating issue when working with remote servers through SSH. The symptoms appear when using text editors (both Vim and Nano) on CentOS servers (versions 5.5 through 6) from my Mac OS X Lion Terminal:

$ ssh user@server.example.com
[remote]$ nano important.conf
# Or alternatively:
[remote]$ vim nginx.conf

The editor would exhibit two primary symptoms:

  1. Cursor jumping unpredictably when using arrow keys
  2. Character garbling when editing existing text

This isn't just an annoyance - it's actively harmful to productivity. When editing configuration files, I'd often find:

# What I typed:
Listen 8080
# What actually appeared after saving:
Lis ten8080

Or worse:

# Intended:
AllowOverride All
# Result:
All owOverrideAll

After extensive troubleshooting, I identified three potential culprits:

  • Terminal encoding mismatch between local and remote systems
  • Incorrect TERM environment variable setting
  • Missing/conflicting locale settings on the remote server

Solution 1: Force UTF-8 Encoding

Add these lines to your SSH config (~/.ssh/config):

Host *
    SendEnv LANG LC_*
    ServerAliveInterval 60
    TCPKeepAlive yes
    EscapeChar none
    Protocol 2
    AddressFamily inet

And on the remote server, ensure your locale is set:

$ sudo localedef -v -c -i en_US -f UTF-8 en_US.UTF-8
$ echo 'export LC_ALL=en_US.UTF-8' >> ~/.bashrc
$ echo 'export LANG=en_US.UTF-8' >> ~/.bashrc

Solution 2: Correct TERM Variable

Before SSHing, set your terminal type:

$ export TERM=xterm-256color
$ ssh user@server

Or add this to your remote .bashrc:

case "$TERM" in
    xterm*) color_prompt=yes;;
esac

Solution 3: Alternative Terminal Testing

Try different terminal emulators as a test:

$ ssh -t user@server.example.com TERM=vt100 nano test.txt
$ ssh -t user@server.example.com TERM=screen vim test.txt

For Vim users experiencing this issue, add to your ~/.vimrc:

set encoding=utf-8
set termencoding=utf-8
set fileencodings=utf-8
set ttyfast
set lazyredraw

Create a wrapper script called sshfix:

#!/bin/bash
TERM=xterm-256color ssh -o 'SendEnv LANG LC_*' "$@"

Make it executable:

$ chmod +x ~/bin/sshfix

Then use it instead of regular ssh:

$ sshfix user@problem.server