23

I need my $TERM to be xterm-256color outside of tmux (in "plain" terminal with zsh), but screen-256color inside tmux.

First I tried:

  • add export TERM='xterm-256color' to my ~/.zshrc.
  • add set -g default-terminal "screen-256color" to my ~/.tmux.conf

Now, when I open terminal (say, xterm), TERM is xterm-256color, which is correct. But when I run tmux, TERM is again xterm-256color!

Then I tried to comment out line in my ~/.zshrc. Now, when I open terminal, TERM is xterm, and when I run tmux, TERM is screen-256color. So it seems if I set TERM in the .zshrc, tmux firstly sets TERM to screen-256color, runs shell (which is zsh), and zsh reads .zshrc and resets TERM to xterm-256color.

So, how to make TERM to be xterm-256color in "plain" terminal, and screen-256color in tmux?

6
  • 5
    Set the TERM for xterm in the xterm configuration (X resources) and that for tmux in the tmux configuration. There's no reason you should do any of that in zsh. Jun 25, 2014 at 9:57
  • Hmm, but I also use other terminal emulators: say, gnome-terminal and quake-style drop-down console "altyo" github.com/linvinus/AltYo , still can't find the way to set correct TERM in these terminals Jun 25, 2014 at 10:02
  • 1
    Well those applications are responsible to set their TERM properly. For gnome-terminal, that should probably be gnome-256color... So it's those applications you need to configure properly, not zsh. The reason they use xterm is probably to avoid problems when sshing to machines that don't have the more specific terminfo entries. If you know you're only sshing to machines with an exhaustive terminfo database, then you can and should change that in the applications themselves. Jun 25, 2014 at 10:16
  • And if you need to add a .zshrc kludge, IMO, that should be on machines that have incomplete terminfo databases (to replace xterm-256color with xterm if xterm-256color s not supported, though it would be even better to add those entries in our own ~/.terminfo database). Jun 25, 2014 at 10:20
  • We should set term in the terminal emulator, not in .zshrc. It is not the correct way.
    – jdhao
    Oct 22, 2018 at 17:00

2 Answers 2

27

The TERM environment variable should be set by the application that is acting as your terminal. This is the whole point of the thing: letting programs running inside them know what terminal is being used and hence what sort of features it supports.

Zsh is not a terminal. It is a shell. It might care what your TERM is set to if it wants to do special things, but it should not be responsible for setting it. Instead it is responsible for setting variables such as ZSH_VERSION which can be used by scripts or other child processes to understand what behavior to expect from their parent shell.

Instead, you need to check the configuration for whatever terminal application you are using and ask it to report itself properly. For example you can do this for xterm by adding this line to the ~/.Xdefaults file it uses for configuration values:

xterm*termName: xterm-256color

It appears gnome-terminal does the idiotic thing of reading what your xterm configuration would be instead of having it's own. This might get you by in some cases but is should more properly be set to vte-256color. This appears to be a long standing gripe against it (and some other VTE based terminal emulators). A common way to hack around this is exploit another value it does set:

if [ "$COLORTERM" = "gnome-terminal" ]; then
    export TERM=vte-256color
fi 

But this brings you back around to your problem with tmux, so you would have to account for that by not resetting TERM if it is already something like "screen-256color" or "screen":

if [ "$COLORTERM" = "gnome-terminal" -a "$TERM" =~ xterm.* ]; then
    export TERM=vte-256color
fi

For other terminals you will need to lookup their proper configuration routines.

4
  • 2
    zsh is not responsible for setting $SHELL. login is responsible for setting it, and you are responsible to change that to something else if you want to tell applications (xterm, vi...) which shell you want as your prefered shell. zsh is responsible for setting $ZSH_VERSION and a few documented special shell variables, but it doesn't touch $SHELL. Jun 27, 2014 at 21:23
  • 1
    @StéphaneChazelas That was sloppy of me, thanks for the correction.
    – Caleb
    Jun 27, 2014 at 21:38
  • Thanks for this, it made me look for how konsole set TERM rather than putting it in my bashrc. Found it set in the profile's General tab, Environment, changed it from xterm to xterm-256color Nov 9, 2018 at 19:07
  • worth noting that under my vanilla deb10 install GNOME Terminal reports truecolor instead of gnome-terminal for $COLORTERM and so the above detection mechanism may not work. XTERM does not appear to set this value at all, it may be valid to check for any value. this term type is partially discussed in this gist possibly elsewhere: gist.github.com/XVilka/8346728#true-color-detection Oct 27, 2019 at 17:58
12

Inside your .zshrc, put

[[ -n $TMUX ]] && export TERM="xterm-256color"

And, inside your .tmux.conf

set -g default-terminal "screen-256color"
1
  • 4
    Or [[ $TMUX != "" ]] && export TERM="screen-256color" This way zsh will set TERM only if called within a tmux session
    – Titou
    May 19, 2017 at 9:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .