SSH: Behavior of SetEnv for TERM variable
Solution 1:
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.)