linux - SSH TERM detection

07
2014-07
  • marcwho

    My ssh config file has accept env set as:

    AcceptEnv LANG LC_*
    

    I am a bit confused how when I ssh through some clients my TERM variable is set as xterm256-color, and other clients TERM is set as vt100. My .bashrc and /etc/profile do not have anything that is setting the TERM variable.

  • Answers
  • grawity

    $TERM is special – it is not sent as an environment variable (which wouldn't make sense for non-Unix systems anyway), but rather as a special "terminal type" field when establishing a pseudo-terminal channel, per RFC 4254 § 6.2.

    6.2. Requesting a Pseudo-Terminal

    A pseudo-terminal can be allocated for the session by sending the following message.

    byte      SSH_MSG_CHANNEL_REQUEST
    uint32    recipient channel
    string    "pty-req"
    boolean   want_reply
    string    TERM environment variable value (e.g., vt100)
    uint32    terminal width, characters (e.g., 80)
    uint32    terminal height, rows (e.g., 24)
    uint32    terminal width, pixels (e.g., 640)
    uint32    terminal height, pixels (e.g., 480)
    string    encoded terminal modes
    
  • l0b0

    $TERM is set by the terminal, that is, the parent process of the shell you are running locally. It is used by applications to determine what the capabilities of the terminal is, for example whether it supports colour. It's very useful to forward this to any other hosts you connect to, since otherwise they would lose this knowledge of the capabilities about the end user terminal.

    See for example Prevent SSH client passing TERM environment variable to server?


  • Related Question

    windows server 2008 - Use ~.ssh/config to always set TERM=cygwin for certain hosts?
  • Sören Kuklau

    I use WinSSHd on several Windows servers. To access them from my Mac (and presumably, just about any Unix-based terminal), I need to set the TERM environment variable to cygwin, e.g.:

    TERM=cygwin ssh someserver.com
    

    I can also use the .ssh/config to set certain defaults for that server, such as a different user and non-default port:

    host someserver.com
        User SomeDifferentDude
        Port 22222
    

    However, I apparently can't set environment variables that way. I haven't found anything in man ssh_config, anyway. Is there a way to set the default terminal emulation (and/or any environment variable) per host?


  • Related Answers
  • Gilles

    You would typically set the environment variable on the server side.

    If WinSSHd is sufficiently like openssh (the usual unix implementation of ssh), you can define an environment file (~/.ssh/environment on unix) and put TERM=cygwin there.

    You can also set the environment variable in your shell initialization file. Since you mention cygwin, this is presumably ~/.bash_profile where ~ is your cygwin home directory. You should set it conditionally, in case you also use cygwin on other terminal types; for example, to set it only if you are logging in over ssh (again, assuming WinSSHd is sufficiently like openssh):

    if [ -n "$SSH_CLIENT" ]; then
      export TERM=cygwin
    fi
    
  • Sören Kuklau

    It turns out there's a much better solution — WinSSHd supports Unix's terminfo format, so all I had to do is copy the proper terminfo file (in the case of OS X: xterm-color) into its directory, and the TERM=cygwin setting become unnecessary.

  • indirect

    You can use SendEnv TERM to set the TERM on the server to be the same as the TERM on your local machine.