8

I just added this to my .bashrc to get colorized output with less:

# Colorize less man pages.
export LESS_TERMCAP_md=$'\e[01;34m'
export LESS_TERMCAP_us=$'\e[01;33m'
export LESS_TERMCAP_so=$'\e[01;44;37m'
export LESS_TERMCAP_mb=$'\e[01;31m'
export LESS_TERMCAP_mr=$'\e[01;35m'
export LESS_TERMCAP_me=$'\e[00m'
export LESS_TERMCAP_ue=$'\e[00m'
export LESS_TERMCAP_se=$'\e[00m'

... and now all of a sudden certain commands (seems to be related to displaying environment variables) produce color output that matches these new settings. Am I escaping wrong? Or is this intentional behavior? I tried a few other escape variations, but they didn't work with less.

For example, here is a screenshot of an env command.

env command

php -i also has colorized output, but only on the environment variables section.

php -i command

3 Answers 3

4

This is normal behavior. These environment variables contain escape sequences that cause the terminal to change its foreground color. You get the same visual effect when any program outputs them, be it less or env.

These variables need to contain the actual escape characters, less doesn't do any postprocessing on them.

Normally you can put less configuration variables in your lesskey file, but this doesn't work for the LESS_TERMCAP_xx variables, because less reads them before it reads the lesskey file (as of less 444). So you have no choice but to put them in the environment.

If you want these variables to apply only to man and not to other uses of less, you can use an alias for man that sets the PAGER variable to a wrapper script that sets the environment variables.

#!/bin/sh
escape=␛     # a literal escape character
export LESS_TERMCAP_md=$escape'[01;34m'
…
exec less "$@"

(Alternatively, use #!/bin/bash on the first line and you can use the #'\e' syntax to get an escape character. On systems where /bin/sh is dash, using /bin/sh is very slightly faster, although it may not be noticeable in practice.)

Call this script less-color, and add alias man='PAGER=less-color man' to your ~/.bashrc or ~/.zshrc. On some systems, instead of creating an alias, you can tell man to use a different pager by setting the MANPAGER environment variable: export MANPAGER=less-color in your ~/.profile.

1

I assume that you've mistakenly set those LESS_* variables' values to strings that contain actual escape characters, as opposed to strings that contain a backslash followed by an e. Thus every time you display those values, they change the color of your terminal.

I'd look very carefully at the settings you made in your .bashrc, and ensure they're correct. I suspect that all you need to do is eliminate the dollar sign.

2
  • Removing the dollar sign messes up my man pages. For example, man top = \e[01;34mSYNOPSIS\e[00m instead of colorizing the word "SYNOPSIS".
    – Jeff
    Aug 18, 2013 at 18:16
  • The dollar sign didn't work. Can you think of a workaround? Maybe a way to restrict those LESS variables to only be used on man pages?
    – Jeff
    Aug 18, 2013 at 18:46
0

As @Gilles points out in his answer, this is an expected behaviour.

Let me just add couple info. LESS_TERMCAP_xx override TERMCAP capabilities. This overriding is managed by less itself in screen.c and the value is just used later on as if it was returned by TERMCAP library. That means it has to be raw sequence of control characters.

My account on how to "fix" this is to wrap less itself

$ cat ~/bin/less 
#!/bin/bash

# Start bold mode
export LESS_TERMCAP_md=$'\e[1;37m'
# Start standout mode
export LESS_TERMCAP_so=$'\e[1;37;41m'
# End standout mode
export LESS_TERMCAP_se=$'\e[0m'
# Start underlining
export LESS_TERMCAP_us=$'\e[4;93m'
# End underlining
export LESS_TERMCAP_ue=$'\e[0m'
# End all mode like so, us, mb, md and mr
export LESS_TERMCAP_me=$'\e[0m'

exec /usr/bin/less "$@"
2
  • Funny, I am working on this right now and it's looking good. Do you have a version that also works with #!/bin/sh (which is dash, in my case)? I can't figure out how to insert a literal ESC character with vim.
    – Jeff
    Aug 19, 2013 at 10:28
  • 1
    @Jeff Just from top of my head you can always do something like export LESS_TERMCAP_me="$(printf '\e[0m')". Actually if you look at @Gilles answer, he is claiming export LESS_TERMCAP_me=$escape'[0m' should work with /bin/sh too. Aug 19, 2013 at 10:32

You must log in to answer this question.

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