9

I want to set the TERM environment variable to a different value for each of my remote machines, so i used SetEnv TERM=myTermForRemoteVar in ~/.ssh/config. The remote machine still sees TERM=myLocalTermVar.

I added AcceptEnv TERM in /etc/ssh/sshd_config on the remote machine. No luck still.

I tried just for testing purposes SetEnv FOO=smth locally and AcceptEnv FOO. This works perfectly and the remote machine sees FOO=smth.

Is TERM treated specially by ssh? SetEnv works in general but not for TERM. Anyone else seeing this behavior? It is not documented at least. Is this a bug?

3
  • I must say I am experiencing the same behaviour in different variations of ssh servers and clients (as far as I remember). I was always too lazy to dig for the answers. I know there are workarounds (for others seeing this see for example serverfault.com/questions/302159/… ) but I am more interested in the rationale behind that particular behaviour and the explanation.
    – nert
    Feb 12 '20 at 22:27
  • 2
    There is a patch to make it accept SetEnv TERM=... and do the right thing as of today :) github.com/openssh/openssh-portable/pull/224 Jan 20 at 5:16
  • I use this syntax for send custom TERM variable to remote host: TERM=MyOwnTerm ssh host
    – Oxyd
    Feb 1 at 4:07
11

Update 2021-06-04: "allow ssh_config SetEnv to override $TERM" was just committed to openssh-portable. I assume it's not in a release yet, but I believe this means that, someday soon-ish, we should be able to override TERM in ~/.ssh/config!


This thread on the openssh-unix-dev seems to indicate that TERM is indeed special, and you can't set it via SetEnv. Here's my reading of things:

As noted in that thread, when the SSH client requests a new PTY from sshd, the request includes an explicit TERM value (see RFC4254, "The Secure Shell (SSH) Connection Protocol", section 6.2). This is separate from any environment variables the client wishes to send.

In OpenSSH's ssh.c, function ssh_session2_setup, OpenSSH unconditionally reads the PTY request's TERM value from your current environment, without any regard to any SetEnv directives. (You can see environment variables, including those from SetEnv, being sent separately in clientloop.c, function client_session2_setup.)

Then, on the server side, session.c's do_setup_env function sets up the environment for the new shell in the reverse order from how the client sends it: first it sets environment variables from s->env, then it sets TERM from the PTY request's TERM value (s->term), overwriting any value for TERM sent as a normal environment variable.

Because of this order of operations on the server, a SetEnv TERM will always be overridden by the value of TERM in the ssh client's environment, not from any SetEnv.

There seem to be good arguments for changing the behavior of OpenSSH in this regard in the aforementioned thread, but I take it no action came of it. At least one person in that thread felt strongly that the remote host's init files should be the one to modify TERM if needed. (I disagree, personally.)

1
  • 1
    Thank you for this detailed answer!
    – Lazarus535
    Jun 24 '20 at 10:46

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.