33

On my local terminal, I have TERM=konsole-256color, but not all remote machine I connect to have this definition.

Is it possible to make ssh change the TERM on remote machine? Without changing .bash* scripts on remote machine, just by changing configuration on my local desktop?

5 Answers 5

18

I have added the following alias to my .bashrc file. It uses O G's answer but wraps it in an alias. Works like a charm ;)

# Force xterm-color on ssh sessions
alias ssh='TERM=xterm-color ssh'
4
  • This works if I use ssh from a terminal. But I also have several scripts that run ssh, and the alias isn't expanded for them. Is there any way I can avoid making a seperate alias for each of them?
    – Thayne
    Sep 11, 2017 at 19:03
  • 1
    If your script needs a specific TERM value, I think it would be best to just set that varialble in the script itself. Or is that not an option?
    – Johan
    Sep 12, 2017 at 9:22
  • That isn't really an option. Also, these scripts selects a server based on some parameters and opens an ssh session to that server (or possibly servers in a tmux session), the scripts themselves don't depend on the TERM value.
    – Thayne
    Sep 13, 2017 at 1:44
  • 2
    In that case you could include your bash profile, or a separate aliases script into the script with: shopt -s expand_aliases; source ~/.bash_aliases
    – Johan
    Sep 13, 2017 at 8:07
12

On 2021-06-04, "allow ssh_config SetEnv to override $TERM" was committed to openssh-portable, which sounds like it will let you set SetEnv TERM in ~/.ssh/config, such as in a Host directive. (Or it will let you as soon as a release is cut with this patch, presumably.)

1
  • Cool. This is the new correct answer. Just edit ~/.ssh/config as long as you're running a post 2021-06-04 commit of ssh and sshd.... Great find!
    – erwin
    Sep 15, 2021 at 8:55
10

man ssh:

     ssh reads ~/.ssh/environment, and adds lines of the format
     “VARNAME=value” to the environment if the file exists and users are
     allowed to change their environment.  For more information, see the
     PermitUserEnvironment option in sshd_config(5).

Edit:

Rats, I hoped it could be on the local side, still, if there's a will, there's a way. man ssh_conf:

SendEnv
             Specifies what variables from the local environ(7) should be sent
             to the server.  Note that environment passing is only supported
             for protocol 2.  The server must also support it, and the server
             must be configured to accept these environment variables.  Refer
             to AcceptEnv in sshd_config(5) for how to configure the server.
             Variables are specified by name, which may contain wildcard char-
             acters.  Multiple environment variables may be separated by
             whitespace or spread across multiple SendEnv directives.  The
             default is not to send any environment variables.

Depending on the configuration of sshd on the receiving end this may or may not fulfil the requirement of "no remote file modification".

2
  • 1
    Yes, but this is configuration on remote side, and I need/want something that changes only on local end.
    – user13185
    Aug 17, 2011 at 16:47
  • 5
    SendEnv is not related. It can possibly send additional env variables, but: 1. it cannot modify them, and 2. TERM is sent anyway, even if it's not listed in SendEnv.
    – user13185
    Aug 17, 2011 at 19:52
9
TERM=vt100 ssh some.host.name

On remote, execute echo $TERM.

3
  • 2
    I though about it, but I want it set only for a subset of hosts I ssh to, so issuing TERM=... ssh all the time will not work. and remembering which hosts have old termcap info, and then changing command on the fly is not nice either.
    – user13185
    Aug 17, 2011 at 16:48
  • Per-host configuration is supported only in /etc/ssh/ssh_config, however I know of no configuration value to support terminal schema mapping per host.
    – O G
    Aug 17, 2011 at 16:53
  • It can also be done in ~/.ssh/config, which I know, but I also can't find any option to modify environment sent to remote server. Was hoping that I missed something.
    – user13185
    Aug 17, 2011 at 17:03
6

Here's my quick and dirty solution I just threw together. I'd prefer something better. I guess I could use a shell script instead. Adjusting TERM values is left as an exercise to the reader.

# To move into a separate plugin...
function ssh {
   if [[ "${TERM}" = screen* || konsole* ]]; then
     env TERM=screen ssh "$@"
   else
     ssh "$@"
   fi
}

Ideally, it would do something like check the TERMs on the other side, using the ControlPersist stuff to prevent long delays for multiple connections.

3
  • Thanks! I did something like this, but instead of checking for specific values of $TERM with an if/else construct, I'm using $(echo -n "$TERM" | sed -e s/tmux/screen/) to unconditionally replace the problematic "tmux" in my local term with the more universally accepted "screen" type (source here). Dec 1, 2015 at 20:20
  • @wincent if is preferred: you don't fork external processes. Keep our Planet green.
    – gavenkoa
    Jun 1, 2021 at 9:13
  • even better than the if or sed: the Shell Parameter Expansion ${TERM/tmux/screen}
    – clausavram
    Apr 26 at 12:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy