Bash – Color codes in bash $PS1 not working in tmux

bashprompttmux

I have a colorized prompt set up in my .bash_profile:

export PS1="\[\033[0:33m\]testprompt@\h\[\033[00m\] "

Outside of tmux I get a colored prompt reading testprompt@hostname.

Inside a tmux session, the text is set but the prompt is not colorized. Other programs output color normally.

I've set a color terminal in .tmux.conf:

set -g default-terminal "xterm-256color"

I'm using the default terminal on macOS. Bash and tmux are the latest versions from the homebrew package manager. The same version of bash running inside tmux and outside.

The following environment variables are exactly the same inside and outside of tmux:

$ echo $PS1
\[\033[0:33m\]testprompt@\h\[\033[00m\]`
$ echo $TERM
xterm-256color
$ echo $SHELL
/usr/local/bin/bash
$ echo $BASH_VERSION
4.4.23(1)-release

Color works perfectly for other commands inside tmux, like ls -la and git log. The fish shell has a color prompt inside tmux. Opening a new bash instance again within tmux doesn't make any difference – still no color. .bash_profile is being read and $PS1 is being set. The prompt colors work in screen and in "raw" bash outside of tmux, just not in tmux. What am I missing?

Best Answer

Whilst it is correct that you must always set the TERM environment variable to match your terminal type, and not blithely and erroneously assume that your terminal type is xterm-*, this is in fact nothing to do with the problem, as the TERM environment variable has no bearing upon literal control sequences embedded in your prompt.

The problem is that you are using sub-parameters in your control sequence, not parameters. Parameters are separated by semi-colon ;, as specified in ECMA-48:1991 § 5.4.2. Sub-parameters are separated by colon :, as specified in ITU-T T.416:1993 § 13.1.8.

Your outer terminal emulator is apparently one of the ones that handles sub-parameters with a bodge that treats them as parameters. Thus CSI 0 : 3 3 m is treated as SGR 0 and SGR 33. Other terminal emulators are stricter about processing control sequences correctly, or do not yet implement sub-parameter support. They can variously treat it as SGR 0 with a sub-parameter of 33, plain SGR 0 (taking the first number), or only SGR 33 (taking the last number).

Terminal emulators did not support sub-parameters at all some years ago, so this is something that is changing; and it is to be hoped that eventually they will all support sub-parameters properly. In which case your prompt will be just plain universally wrong. ☺

Personally, I prefer the Z shell, where one can use sequences like %F{yellow} in a prompt without having to worry about what the control sequences are, getting them right, and marking them as non-spacing.

Related Question