327

I spend most of my time working in Unix environments and using terminal emulators. I try to use color on the command line, because color makes the output more useful and intuitive.

What options exist to add color to my terminal environment? What tricks do you use? What pitfalls have you encountered?

Unfortunately, support for color varies depending on terminal type, OS, TERM setting, utility, buggy implementations, etc.

Here are some tips from my setup, after a lot of experimentation:

  1. I tend to set TERM=xterm-color, which is supported on most hosts (but not all).
  2. I work on a number of different hosts, different OS versions, etc. I use everything from macOS X, Ubuntu Linux, RHEL/CentOS/Scientific Linux and FreeBSD. I'm trying to keep things simple and generic, if possible.
  3. I do a bunch of work using GNU screen, which adds another layer of fun.
  4. Many OSs set things like dircolors and by default, and I don't want to modify this on a hundred different hosts. So I try to stick with the defaults. Instead, I tweak my terminal's color configuration.
  5. Use color for some Unix commands (ls, grep, less, vim) and the Bash prompt. These commands seem to use the standard "ANSI escape sequences". For example:

    alias less='less --RAW-CONTROL-CHARS' export LS_OPTS='--color=auto' alias ls='ls ${LS_OPTS}' 

I'll post my .bashrc and answer my own question Jeopardy Style.

4
  • 1
    fyi my approach (see answer below) addresses issues with OSX and Linux differences, for example color on one is ls -G and on the other is ls --color-auto Commented Jan 13, 2015 at 22:30
  • 2
    Did anybody see a tool to color columns? That is a column -t --color? Commented Feb 13, 2018 at 23:09
  • 1
    @TomášPospíšek have you looked into grc ? Commented Sep 5, 2021 at 19:31
  • It is generally a very poor idea to set TERM manually. unix.stackexchange.com/questions/108410/… Commented Feb 2, 2024 at 20:31

25 Answers 25

155

Here are a couple of things you can do:

Editors + Code

A lot of editors have syntax highlighting support. vim and emacs have it on by default. You can also enable it under nano.

You can also syntax highlight code on the terminal by using Pygments as a command-line tool.

grep

grep --color=auto highlights all matches. You can also use export GREP_OPTIONS='--color=auto' to make it persistent without an alias. If you use --color=always, it'll use colour even when piping, which confuses things.

ls

ls --color=always

Colors specified by:

export LS_COLORS='rs=0:di=01;34:ln=01;36:mh=00:pi=40;33' 

(hint: dircolors can be helpful)

PS1

You can set your PS1 (shell prompt) to use colours. For example:

PS1='\e[33;1m\u@\h: \e[31m\W\e[0m\$ ' 

Will produce a PS1 like:

[yellow]lucas@ubuntu: [red]~[normal]$

You can get really creative with this. As an idea:

PS1='\e[s\e[0;0H\e[1;33m\h \t\n\e[1;32mThis is my computer\e[u[\u@\h: \w]\$ ' 

Puts a bar at the top of your terminal with some random info. (For best results, also use alias clear="echo -e '\e[2J\n\n'".)

Getting Rid of Escape Sequences

If something is stuck outputting colour when you don't want it to, I use this sed line to strip the escape sequences:

sed "s/\[^[[0-9;]*[a-zA-Z]//gi" 

If you want a more authentic experience, you can also get rid of lines starting with \e[8m, which instructs the terminal to hide the text. (Not widely supported.)

sed "s/^\[^[8m.*$//gi" 

Also note that those ^[s should be actual, literal ^[s. You can type them by pressing ^V^[ in bash, that is Ctrl + V, Ctrl + [.

2
  • 7
    Escapes should be enclosed in \[...\] or else commands in second line will overwrite the first line. PS1='[\e[33;1m]\u@\h: [\e[31m]\W\e[0m\$ ' Commented Aug 29, 2013 at 19:09
  • The ls --color=always doesn't work. @Michael Durrant' s approach is better for this: ls --color=al > /dev/null 2>&1 && alias ls='ls -F --color=al' || alias ls='ls -G' Commented Feb 1, 2019 at 6:51
115

I also use:

export TERM=xterm-color export GREP_OPTIONS='--color=auto' GREP_COLOR='1;32' export CLICOLOR=1 export LSCOLORS=ExFxCxDxBxegedabagacad 

And if you like colorizing your prompt, defined color vars can be useful:

export COLOR_NC='\e[0m' # No Color export COLOR_BLACK='\e[0;30m' export COLOR_GRAY='\e[1;30m' export COLOR_RED='\e[0;31m' export COLOR_LIGHT_RED='\e[1;31m' export COLOR_GREEN='\e[0;32m' export COLOR_LIGHT_GREEN='\e[1;32m' export COLOR_BROWN='\e[0;33m' export COLOR_YELLOW='\e[1;33m' export COLOR_BLUE='\e[0;34m' export COLOR_LIGHT_BLUE='\e[1;34m' export COLOR_PURPLE='\e[0;35m' export COLOR_LIGHT_PURPLE='\e[1;35m' export COLOR_CYAN='\e[0;36m' export COLOR_LIGHT_CYAN='\e[1;36m' export COLOR_LIGHT_GRAY='\e[0;37m' export COLOR_WHITE='\e[1;37m' 

And then my prompt is something like this:

case $TERM in xterm*|rxvt*) local TITLEBAR='\[\033]0;\u ${NEW_PWD}\007\]' ;; *) local TITLEBAR="" ;; esac local UC=$COLOR_WHITE # user's color [ $UID -eq "0" ] && UC=$COLOR_RED # root's color PS1="$TITLEBAR\n\[${UC}\]\u \[${COLOR_LIGHT_BLUE}\]\${PWD} \[${COLOR_BLACK}\]\$(vcprompt) \n\[${COLOR_LIGHT_GREEN}\]→\[${COLOR_NC}\] " 

$(vcprompt) is calling a python script in my ~/sbin which prints version control information about the current path. It includes support for Mercurial, Git, Svn, Cvs, etc. The author of the script has the source here.

Bash prompt screenshot

This is the full source of my prompt configuration:

9
  • See here for the solution to a line problem I got when I used the above PS1: stackoverflow.com/questions/5087036/… Commented Sep 10, 2012 at 15:53
  • I've updated the answer to reflect the escaped brackets for the colors in the prompt. Thanks! Commented Nov 27, 2014 at 7:57
  • 1
    $LSCOLORS and $CLICOLOR are for BSD ls. GNU ls (Linux) uses $LS_COLORS with a different syntax. As GNU feels like home to me, I use LSCOLORS=exgxfxDacxBaBaCaCaeaEa to mimic GNU's colors on BSD. Commented Jan 12, 2015 at 22:22
  • grep: warning: GREP_OPTIONS is deprecated; please use an alias or script Commented Nov 23, 2016 at 21:19
  • 1
    You may need to source the .bashrc file for the modification to be effective. You can do it with the following command. source /path/to/.bashrc Commented Jun 4, 2019 at 18:43
20

grep and ls have already been mentioned, if you want a lot more colors check out Generic Coloriser, its initial purpose was to colorize logfiles, but right out of the box it also colorizes ping, traceroute, gcc, make, netstat, diff, last, ldap, and cvs.

It's easily extended if you know regexes. I've added ps and nmap to the list (if you get into grc I'll be more than glad to share the .conf files for those two tools)

(Btw, to install it via synaptic, pacman, and alike you might have better luck searching for "grc")

4
  • grc now supports ps by default. I'd be interested in your nmap colorings. See also my answer for aliasing all of these in a way that will absorb new commands when you upgrade grc. Commented Jan 13, 2015 at 3:05
  • I noticed that. here's my conf.nmap (and everything else, really) gist.github.com/sygo/844982#file-conf-nmap - I noticed you work in infosec, you might find conf.hexdump interesting, I haven't finished it yet though. Commented Feb 6, 2015 at 21:29
  • Thanks @Sygo. I've forked and revised your gist. I've never actually committed data with git (let alone github's gists) and I cannot figure out how to propose merging it back to you (I'm guessing this is because gists are too simplified). Commented Feb 7, 2015 at 1:54
  • I suspect you can't because it's a gist and not a proper repository. I did check out your fork though and I'm definitely giving your version a go. I'm curious as what that hex dump one will turn into... Commented Feb 7, 2015 at 2:48
18

I've honed my .bashrc over the years to work on both OSX and Ubuntu.
I've also reduced it in size to 28 lines with compact condition statements.
With it, my PS1 prompt looks like: enter image description here

with time in red, username in green, machine name in light blue, pwd in darker blue and git branch in yellow.

Feature of my PS1 prompt:

  • shows git branch!
  • long directory paths (more than 6 elements) are 'trimmed' to show top 3 and bottom 3 directories with _ between then (that's the pwd sed part of LOCATION).
  • carriage return at the end so that prompt is always on the left!

The relevant lines from my .bashrc file are:

git_branch () { git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/'; } HOST='\033[02;36m\]\h'; HOST=' '$HOST TIME='\033[01;31m\]\t \033[01;32m\]' LOCATION=' \033[01;34m\]`pwd | sed "s#\(/[^/]\{1,\}/[^/]\{1,\}/[^/]\{1,\}/\).*\(/[^/]\{1,\}/[^/]\{1,\}\)/\{0,1\}#\1_\2#g"`' BRANCH=' \033[00;33m\]$(git_branch)\[\033[00m\]\n\$ ' PS1=$TIME$USER$HOST$LOCATION$BRANCH PS2='\[\033[01;36m\]>' 

For ls with colors when available and no errors when not (i.e. OSX):

ls --color=al > /dev/null 2>&1 && alias ls='ls -F --color=al' || alias ls='ls -G' 
3
  • 1
    Colors are available for ls on OS X, but it is done by using export CLICOLOR=1. Commented Mar 4, 2015 at 9:47
  • 3
    @ThomasW but not on linux :-p The guy uses both. Commented Dec 4, 2015 at 16:58
  • 1
    Nonetheless, ThomasW is correct to point out that the answer is erroneous in saying that colours are not available with ls on MacOS 10. The answer is also erroneous in that the prompt strings here are in fact faulty. They do not correctly balance \[ and \], and have caused problems for at least one person copying this answer. Commented Nov 17, 2016 at 4:16
12

Colors for man pages (more detail):

function _colorman() { env \ LESS_TERMCAP_mb=$'\e[1;35m' \ LESS_TERMCAP_md=$'\e[1;34m' \ LESS_TERMCAP_me=$'\e[0m' \ LESS_TERMCAP_se=$'\e[0m' \ LESS_TERMCAP_so=$'\e[7;40m' \ LESS_TERMCAP_ue=$'\e[0m' \ LESS_TERMCAP_us=$'\e[1;33m' \ LESS_TERMCAP_mr=$(tput rev) \ LESS_TERMCAP_mh=$(tput dim) \ LESS_TERMCAP_ZN=$(tput ssubm) \ LESS_TERMCAP_ZV=$(tput rsubm) \ LESS_TERMCAP_ZO=$(tput ssupm) \ LESS_TERMCAP_ZW=$(tput rsupm) \ GROFF_NO_SGR=1 \ "$@" } alias man="LANG=C _colorman man" function perldoc() { command perldoc -n less "$@" |man -l -; } 

Colors for grep (1;32 is bright green, see other posts here for other colors):

GREP_OPTS='--color=auto' # for aliases since $GREP_OPTIONS is deprecated GREP_COLOR='1;32' # (legacy) bright green rather than default red # (new) Matching text in Selected line = green, line numbers dark yellow GREP_COLORS="ms=${GREP_COLOR}:mc=${GREP_COLOR}:ln=33" alias grep='grep $GREP_OPTS' alias egrep='grep -E $GREP_OPTS' alias fgrep='LC_ALL=C grep -F $GREP_OPTS' 

Using LC_ALL=C for fgrep can provide a 140x performance boost

More colors for GNU ls:

# use the config at ~/.dircolors if it exists, otherwise generate anew eval "$( dircolors --sh $(find ~/.dircolors -size +0 2>/dev/null) )" # Usage: _ls_colors_add BASE NEW [NEW...] # Have LS color given NEW extensions the way BASE extension is colored _ls_colors_add() { local BASE_COLOR="${LS_COLORS##*:?.$1=}" NEW if [ "$LS_COLORS" != "$BASE_COLOR" ]; then BASE_COLOR="${BASE_COLOR%%:*}" shift for NEW in "$@"; do if [ "$LS_COLORS" = "${LS_COLORS#*.$NEW=}" ]; then LS_COLORS="${LS_COLORS%%:}:*.$NEW=$BASE_COLOR:" fi done fi export LS_COLORS } _ls_colors_add zip jar xpi # archives _ls_colors_add jpg ico JPG PNG webp # images _ls_colors_add ogg opus # audio (opus now included by default) export CLICOLOR=1 # BSD auto-color trigger (like ls -G but for everything) if ls -ld --color=auto / >/dev/null 2>&1 then alias ls="ls -ph --color=auto" else alias ls="ls -ph" fi 

Install grc (Generic Colouriser) and add it to your aliases:

if type grc grcat >/dev/null 2>&1; then colourify() { # using this as a function allows easier calling down lower if [[ -t 1 || -n "$CLICOLOR_FORCE" ]] then ${GRC:-grc} -es --colour=auto "$@" else "$@" fi } # loop through known commands plus all those with named conf files for cmd in g++ head ld ping6 tail traceroute6 `locate grc/conf.`; do cmd="${cmd##*grc/conf.}" # we want just the command type "$cmd" >/dev/null 2>&1 && alias "$cmd"="colourify $cmd" done # This needs run-time detection. We even fake the 'command not found' error. configure() { if [[ -x ./configure ]]; then colourify ./configure "$@" else echo "configure: command not found" >&2 return 127 fi } unalias ll 2>/dev/null ll() { if [[ -n "$CLICOLOR_FORCE" || -t 1 ]]; then # re-implement --color=auto ls -l --color=always "$@" |grcat conf.ls return ${PIPESTATUS[0]} ${pipestatus[1]} # exit code of ls via bash or zsh fi ls -l "$@" } fi 

Colors for diff: Too much content for a function, use a script and alias it in your rc file (unnecessary if you installed grc):

#!/usr/bin/perl use strict; use warnings; open (DIFF, "-|", "diff", @ARGV) or die $!; my $ydiff = 1; while (<DIFF>) { if (not -t 1) { print; next; } chomp; $ydiff = 0 if /^[ <>\@+-]/ or ($. == 1 && /^\d+[a-z]{1,5}\d+$/); my $color = ""; if (! $ydiff && /^[\@+-<>]/) { $color = (/^[<-](?!--$)/ ? 1 : /^[+>]/ ? 2 : 5); } elsif ($ydiff && /\t {6}([<|>])(?:\t|$)/) { $color = ($1 eq "<" ? 1 : $1 eq ">" ? 2 : 4); } $color ? printf ("\e[1;3%dm%s\e[0;0m\n",$color,$_) : print "$_\n"; } close DIFF; 

Colors for bash prompt:

# Shorten home dir, Cygwin drives, paths that are too long function PSWD() { local p="$*" space A B cols="${COLUMNS:-`tput cols 2>/dev/null || echo 80`}" p="${p/$HOME/\~}" # shrink home down to a tilde if [ -d /cygdrive ] && [ "${p#/cygdrive/?/}" != "$p" ]; then p="${p:10:1}:${p:11}" # /cygdrive/c/hi -> c:/hi fi space="$((${#USER}+${#HOSTNAME}+6))" # width w/out the path if [ "$cols" -lt 60 ]; then echo -n "$N "; space=-29; p="$p$N\b"; fi if [ "$cols" -lt "$((space+${#p}+20))" ]; then # < 20 chars for the command A=$(( (cols-20-space)/4 )) # a quarter of the space (-20 for cmd) if [ $A -lt 4 ]; then A=4; fi # 4+ chars from beginning B=$(( cols-20-space-A*2 )) # half (plus rounding) of the space if [ $B -lt 8 ]; then B=8; fi # 8+ chars from end p="${p:0:$A}..${p: -$B}" fi echo "$p" } PSC() { printf $'\[\e[%sm\]' "${*:-0;0}"; } PR="0;32" # default color used in prompt is green if [ "$(id -u)" = 0 ]; then sudo=41 # root is red background elif [ "$USER" != "${SUDO_USER:-$USER}" ]; then sudo=31 # not root, not self: red text else sudo="$PR" # standard user color fi PROMPT_COMMAND='[ $? = 0 ] && PS1=${PS1[1]} || PS1=${PS1[2]}' PSbase="$(PSC $sudo)\u$(PSC $PR)@\h $(PSC 33)\$(PSWD \w)" PS1[1]="$PSbase$(PSC $PR)\$ $(PSC)" PS1[2]="$PSbase$(PSC 31)\$ $(PSC)" PS1="${PS1[1]}" unset sudo PR PSbase 

demo of bash prompt

7
  • My PSWD() function used to be POSIX-compatible but it's so much easier facilitated using bash/zsh substring handling. See revision 6 for the POSIX version, which involves lots of question marks and wasn't at all adaptable to terminal width. I didn't update the screenshot, but it's only a slight change at the 80 character width. Commented Aug 23, 2017 at 23:09
  • CLICOLOR=1 doesn't work for me with FREEBSD 11.2 Commented Feb 1, 2019 at 6:52
  • 1
    @SimonC. – You might be using GNU utilities on your FreeBSD system rather than the BSD ones. CLICOLOR=1 ls should do the same thing as ls -G using BSD (ls -g on older BSDs). If ls --color works (no error), you're using GNU's ls command and $CLICOLOR is ignored. Commented Feb 4, 2019 at 17:30
  • Thanks. It's really strange then. Putting CLICOLOR=1 in my bashrc doesn't do anything, though when doing echo $CLICOLOR it tells me it's at when. While defining CLICOLOR=1 just before calling ls as you mentioned in your post works. and ls --color return an "illegal option", suggesting I am indeed using BSD ls... not sure what's happening Commented Feb 4, 2019 at 18:58
  • 1
    @SimonC. – You have to actually load your ~/.bashrc for any changes to take effect. Either run source ~/.bashrc or start a new bash session (launch a terminal or run bash). Commented Feb 4, 2019 at 19:03
8

Set a bold/colored prompt. From cyberciti.biz and the BashFAQ

# 'tput bold' will work regardless of the foreground and background colors. # Place the tput output into variables, so they are only execd once. bold=$(tput bold) # This could also be a color. reset=$(tput sgr0) export PS1="\u@\[$bold\]\h\[$reset\]:\w \$ " 

I've also managed to find color settings which are widely supported, and which don't print gobbledygook characters in older environments (even FreeBSD4!), and seems to work fine if TERM=vt100, xterm, xterm-color. (For the most part). From my .bashrc:

# Set some options, based on the OS OS=`uname -s` case "$OS" in "SunOS" ) # Solaris ls doesn't allow color, so use special characters LS_OPTS='-F' alias ls='ls ${LS_OPTS}' ;; "Linux" ) # GNU ls supports colors! # See dircolors to customize colors export LS_OPTS='--color=auto' alias ls='ls ${LS_OPTS}' # Get color support for 'less' export LESS="--RAW-CONTROL-CHARS" # Use colors for less, man, etc. [[ -f ~/.LESS_TERMCAP ]] && . ~/.LESS_TERMCAP export GREP_OPTIONS="--color=auto" ;; "Darwin"|"FreeBSD") # Most FreeBSD & Apple Darwin supports colors export CLICOLOR=true # Get color support for 'less' export LESS="--RAW-CONTROL-CHARS" # Use colors for less, man, etc. [[ -f ~/.LESS_TERMCAP ]] && . ~/.LESS_TERMCAP export GREP_OPTIONS="--color=auto" ;; * ) echo "Unknown OS [$OS]" ;; esac 
1
  • 1
    Or if you want to use ZSH, Phil Gold's prompt at aperiodic.net/phil/prompt is a work of art. Commented Aug 12, 2010 at 9:27
7

Things that have not been said already here:

To colorize the output of your compilations with gcc, there is colorgcc by Johannes Schlüter

To colorize logs, there is multitail

To colorize any stdout, I put together xcol

xcol example

I personally use these from the xcol tool.

#normal=$(tput sgr0) # normal text normal=$'\e[0m' # (works better sometimes) bold=$(tput bold) # make colors bold/bright red="$bold$(tput setaf 1)" # bright red text green=$(tput setaf 2) # dim green text fawn=$(tput setaf 3); beige="$fawn" # dark yellow text yellow="$bold$fawn" # bright yellow text darkblue=$(tput setaf 4) # dim blue text blue="$bold$darkblue" # bright blue text purple=$(tput setaf 5); magenta="$purple" # magenta text pink="$bold$purple" # bright magenta text darkcyan=$(tput setaf 6) # dim cyan text cyan="$bold$darkcyan" # bright cyan text gray=$(tput setaf 7) # dim white text darkgray="$bold"$(tput setaf 0) # bold black = dark gray text white="$bold$gray" # bright white text 

I use these variables in my scripts like so

echo "${red}hello ${yellow}this is ${green}coloured${normal}" 

I also like this little function coloredEcho ( found on Stack Overflow )

function coloredEcho(){ local exp=$1; local color=$2; if ! [[ $color =~ '^[0-9]$' ]] ; then case $(echo $color | tr '[:upper:]' '[:lower:]') in black) color=0 ;; red) color=1 ;; green) color=2 ;; yellow) color=3 ;; blue) color=4 ;; magenta) color=5 ;; cyan) color=6 ;; white|*) color=7 ;; # white or invalid color esac fi tput setaf $color; echo $exp; tput sgr0; } coloredEcho "This text is green" green 

Sorry, not allowed to post more links

3
  • 2
    Hello, how do you make the flags, for the prompt path? I am mentioning the rectangular bars with triangle ends Thanks Commented Dec 21, 2017 at 22:50
  • does it work in a ubuntu gnu terminal as well? Commented Feb 22, 2018 at 16:08
  • lnav is also a great tool to show colorized logfiles Commented May 30, 2018 at 6:18
5

I suggest you check out ZSH and its plugin oh-my-zsh which has one of the most powerfull console features that I saw. One of them is picking theme for your terminal. This is example of my theme... In tty the colors are not so warm but they are the same like in this picture... Any way you will love it!

enter image description here

3
  • 3
    If I could, I would downvote this for the Oh-My-ZSH suggestion. As a systems engineer who works extensively in the Terminal, and as somebody who tried to adopt zsh/oh-my-zsh into my workflow, I can honestly say I would never recommend ZSH to anyody. Sure, you can symlink zsh to a file named after any other shell and emulate that shell, but when you do that it doesn't read your .bashrc, .bash_profile, etc. Also, you cannot put emulate bash in your .zprofile or .zshrc files. For anybody who works with advanced features in BASH, there are many subtleties that will bite you. BASH is a better sh. Commented Jul 12, 2016 at 16:56
  • 3
    The only thing that ZSH has out of the box that is better than BASH is command completion, but even that is programmable in BASH. Maybe somebody who doesn't use the shell except for occasional mundane tasks should adopt ZSH, but it's not for anybody who needs to use the shell extensively. the =~ operator can bite you, the way ZSH handles arrays can bite you, etc. After using ZSH/Oh-My-ZSH for about 9 months I had enough of it. I was using a custom theme that I wrote myself, I ported it to BASH and wrote my own git promptline and I've never looked back. Now I no longer worry about portability Commented Jul 12, 2016 at 17:01
  • 2
    "it has one of the most powerfull console features that I saw. One of them is picking theme for your terminal." Commented Aug 31, 2016 at 10:32
5

There's a good tool for setting up your colours for the ls command - http://geoff.greer.fm/lscolors/

It provides a web-based UI to easily build your desired $LS_COLORS values by selecting colors:

screenshot of lscolors' web page

0
4

For viewing diff output in color, use colordiff.

sudo apt-get install colordiff 

Pipe any diff-format output into colordiff:

output of diff piped into colordiff

This includes some of diff's alternate formats, like -y (side-by-side.)

Alternatively, if invoked standalone (without anything piped into it) then it acts as a wrapper around 'diff', and colors the output. Hence I have this in my .bashrc, to alias 'diff' to colordiff.

# if colordiff is installed, use it if type colordiff &>/dev/null ; then alias diff=colordiff 
1
  • 1
    The .bashrc example is missing the final fi, and could be converted to a single-line command: type colordiff &> /dev/null && alias diff='colordiff' Commented Feb 27, 2019 at 8:05
3

Some text decoration (bold) to easily differentiate between root and non-root shell. For Zsh:

if test $UID = 0 then PS1="%B${PS1}%b " fi 

For Bash:

if test $UID = 0 then PS1="\033[1m${PS1}\033[0m" fi 
2
  • Please specify your shell. The question's only shell specific tag is bash, but I feel your code is not bash. Commented Jan 26, 2012 at 9:21
  • @manatwork: sorry, forgot to mention that it was Zsh. Updated my post. Commented Jan 26, 2012 at 9:53
3

I just wondered the same thing. I have my own approach, but I'm looking for alternatives.

I write bash wrappers around program calls and pipe their output though sed. What I like about sed is that it will modify and echo each line right away => not much buffering. However, I dislike that for every call to a wrapped program the sed code is parsed and compiled.

For example this is what I do to color the output of ip:

# # Colorcodes # NORMAL=`echo -e '\033[0m'` RED=`echo -e '\033[31m'` GREEN=`echo -e '\033[0;32m'` LGREEN=`echo -e '\033[1;32m'` BLUE=`echo -e '\033[0;34m'` LBLUE=`echo -e '\033[1;34m'` YELLOW=`echo -e '\033[0;33m'` # # command: ip # highlight ip addresses, default route and interface names # IP4=$GREEN IP6=$LBLUE IFACE=${YELLOW} DEFAULT_ROUTE=$LBLUE IP_CMD=$(which ip) function colored_ip() { ${IP_CMD} $@ | sed \ -e "s/inet [^ ]\+ /${IP4}&${NORMAL}/g"\ -e "s/inet6 [^ ]\+ /${IP6}&${NORMAL}/g"\ -e "s/^default via .*$/${DEFAULT_ROUTE}&${NORMAL}/"\ -e "s/^\([0-9]\+: \+\)\([^ \t]\+\)/\1${IFACE}\2${NORMAL}/" } alias ip='colored_ip' 
3

For setting the prompt, I have this in my .bashrc file.

#Set variables for foreground colors fgRed=$(tput setaf 1) ; fgGreen=$(tput setaf 2) ; fgBlue=$(tput setaf 4) fgMagenta=$(tput setaf 5) ; fgYellow=$(tput setaf 3) ; fgCyan=$(tput setaf 6) fgWhite=$(tput setaf 7) ; fgBlack=$(tput setaf 0) #Set variables for background colors bgRed=$(tput setab 1) ; bgGreen=$(tput setab 2) ; bgBlue=$(tput setab 4) bgMagenta=$(tput setab 5) ; bgYellow=$(tput setab 3) ; bgCyan=$(tput setab 6) bgWhite=$(tput setab 7) ; bgBlack=$(tput setab 0) #Set variables for font weight and text decoration B=$(tput bold) ; U=$(tput smul) ; C=$(tput sgr0) #NOTE: ${C} clears the current formatting if [[ $USER = "root" ]]; then PS1="${B}${fgRed}\u${C}@\h(\s): ${fgGreen}\w${C} > " else PS1="${B}${fgCyan}\u${C}@\h(\s): ${fgGreen}\w${C} > " fi 

This gives me a prompt that looks something like this:

user@host(bash): ~/bin > 

The working directory is in green. And the user name is bold and cyan unless I ran the shell with sudo, in which case the user name ("root") displays bold and red.

I personally really like having the formatting control characters stored in variables because it makes reading the code for setting the prompt easier. It also makes editing the prompt much easier.

The reason I use tput is that it's supposed to be more universally supported than the weird 033[01;31m\] sequences. Also, as an added bonus, if you do echo $PS1 at the prompt, you will see the raw prompt with colors instead of those unintelligible control sequences.

2

You can try a project that helps on colorizing scripts output also, its named ScriptEchoColor at source forge: http://scriptechocolor.sourceforge.net/

ex.:

echoc "@{lr}text output in light red" echoc "@{bLGu}text outpus in blue, light green background and underlined" echoc "you @{lr} can @{bLGu} mix @{-a} it all too" echoc -x "ls" #executes ls command and colorizes it automatically to be easy to be seen 

The automatic colors are configurable.

This is an example done with it: enter image description here

2

A great general-purpose Python tool for coloring the output of commands is 'colout'

You give it a regex with N groups, followed by a comma separated list of N colors. Any text that matches a group will be displayed in the corresponding color.

So for example, if you're looking at some test output:

python -m unittest discover -v 

Uncolored output of some Python unittests

then you can spruce it up with:

python -m unittest discover -v 2>&1 | colout '(.*ERROR$)|(.*FAIL$)|(\(.*\))' red,yellow,black bold 

Colored output of some Python unittests

See how my regex has three groups (the parenthesis) followed by three colors (and optionally three styles, but I've used a shorthand to set all the colors to 'bold', so the 'black' group, which matches text in brackets, comes out as dark grey.)

Note also how I had to add 2>&1 to the end of the Python invocation, because the output of unittest is on stderr, so I transferred it to stdout so that I could pipe it into colout.

This is generally so easy to use that I often find myself creating new colout invocations on-the-fly, and reusing or modifying them from my command-line history.

The only downside of it is that it comes as a Python package, not a standalone executable, so you need to install it using pip, or sudo python setup.py install.

2

I find Solarized useful. Its a neat project with uniform colors for lots of applications.

http://ethanschoonover.com/solarized https://github.com/altercation/solarized

2

I use color wrapper.

cw is a non-intrusive real-time ANSI color wrapper for common unix-based commands on GNU/linux. cw is designed to simulate the environment of the commands being executed, so that if a person types 'du', 'df', 'ping', etc. in their shell it will automatically color the output in real-time according to a definition file containing the color format desired. cw has support for wildcard match coloring, tokenized coloring, headers/footers, case scenario coloring, command line dependent definition coloring, and includes over 50 pre-made definition files.

It is almost seamless, but once i found that ps in interactive shell returns different output comparing ps in a pipe.

1
  • This sounded promising, but the colors are random at every invocation. Commented Jan 25, 2023 at 3:43
2

You can use my cf for file name coloring on the command line, it's a quick little awk-based colorizer that works via pipes - coloring filenames in Truecolor sRGB.

It's got a brightly colored default configuration and unlike ls it does not suffer a performance penalty for adding new colors. (ls must scan the entire LS_COLORS string for each miss).

https://github.com/AdamDanischewski/cf

cf usage

cf screenshot

0
1

For Mac you can use following as specified here

if [ "$TERM" = xterm ]; then TERM=xterm-256color; fi 
1

If you're wanting to do it on log files.

tail -f example.log | sed \ -e "s/FATAL/"$'\e[31m'"&"$'\e[m'"/" \ -e "s/ERROR/"$'\e[31m'"&"$'\e[m'"/" \ -e "s/WARNING/"$'\e[33m'"&"$'\e[m'"/" \ -e "s/INFO/"$'\e[32m'"&"$'\e[m'"/" \ -e "s/DEBUG/"$'\e[34m'"&"$'\e[m'"/" 

An example of it working and screenshot below:

echo " [timestamp] production.FATAL Some Message\n" \ "[timestamp] production.ERROR Some Message\n" \ "[timestamp] production.WARNING Some Message\n" \ "[timestamp] production.INFO Some Message\n" \ "[timestamp] production.DEBUG Some Message\n" | sed \ -e "s/FATAL/"$'\e[31m'"&"$'\e[m'"/" \ -e "s/ERROR/"$'\e[31m'"&"$'\e[m'"/" \ -e "s/WARNING/"$'\e[33m'"&"$'\e[m'"/" \ -e "s/INFO/"$'\e[32m'"&"$'\e[m'"/" \ -e "s/DEBUG/"$'\e[34m'"&"$'\e[m'"/" 

Prints out like this on Mac:

Mac sed logs to add colour

1

Use the colors before the parts you want to color. This is where I found this gist.github.com/vratiu/9780109.

# Reset Color_Off="\[\033[0m\]" # Text Reset # Regular Colors Black="\[\033[0;30m\]" # Black Red="\[\033[0;31m\]" # Red Green="\[\033[0;32m\]" # Green Yellow="\[\033[0;33m\]" # Yellow Blue="\[\033[0;34m\]" # Blue Purple="\[\033[0;35m\]" # Purple Cyan="\[\033[0;36m\]" # Cyan White="\[\033[0;37m\]" # White # Bold BBlack="\[\033[1;30m\]" # Black BRed="\[\033[1;31m\]" # Red BGreen="\[\033[1;32m\]" # Green BYellow="\[\033[1;33m\]" # Yellow BBlue="\[\033[1;34m\]" # Blue BPurple="\[\033[1;35m\]" # Purple BCyan="\[\033[1;36m\]" # Cyan BWhite="\[\033[1;37m\]" # White # Underline UBlack="\[\033[4;30m\]" # Black URed="\[\033[4;31m\]" # Red UGreen="\[\033[4;32m\]" # Green UYellow="\[\033[4;33m\]" # Yellow UBlue="\[\033[4;34m\]" # Blue UPurple="\[\033[4;35m\]" # Purple UCyan="\[\033[4;36m\]" # Cyan UWhite="\[\033[4;37m\]" # White # Background On_Black="\[\033[40m\]" # Black On_Red="\[\033[41m\]" # Red On_Green="\[\033[42m\]" # Green On_Yellow="\[\033[43m\]" # Yellow On_Blue="\[\033[44m\]" # Blue On_Purple="\[\033[45m\]" # Purple On_Cyan="\[\033[46m\]" # Cyan On_White="\[\033[47m\]" # White # High Intensity IBlack="\[\033[0;90m\]" # Black IRed="\[\033[0;91m\]" # Red IGreen="\[\033[0;92m\]" # Green IYellow="\[\033[0;93m\]" # Yellow IBlue="\[\033[0;94m\]" # Blue IPurple="\[\033[0;95m\]" # Purple ICyan="\[\033[0;96m\]" # Cyan IWhite="\[\033[0;97m\]" # White # Bold High Intensity BIBlack="\[\033[1;90m\]" # Black BIRed="\[\033[1;91m\]" # Red BIGreen="\[\033[1;92m\]" # Green BIYellow="\[\033[1;93m\]" # Yellow BIBlue="\[\033[1;94m\]" # Blue BIPurple="\[\033[1;95m\]" # Purple BICyan="\[\033[1;96m\]" # Cyan BIWhite="\[\033[1;97m\]" # White # High Intensty backgrounds On_IBlack="\[\033[0;100m\]" # Black On_IRed="\[\033[0;101m\]" # Red On_IGreen="\[\033[0;102m\]" # Green On_IYellow="\[\033[0;103m\]" # Yellow On_IBlue="\[\033[0;104m\]" # Blue On_IPurple="\[\033[10;95m\]" # Purple On_ICyan="\[\033[0;106m\]" # Cyan On_IWhite="\[\033[0;107m\]" # White # Various variables you might want for your PS1 prompt instead Time12h="\T" Time12a="\@" PathShort="\w" PathFull="\W" NewLine="\n" 

Remember to keep color to yes in .bashrc file and the color does not change back so end your colored part with "\[\033[0m\]".

2
  • Use the colors before the parts you want to color. This is where i found this gist.github.com/vratiu/9780109 Commented Dec 11, 2021 at 8:14
  • Please edit and add additional info into the answer and not in the comments, that is not what they are for. Also, using code formatting would vastly improve the presentation of your answer. Commented Dec 11, 2021 at 11:55
0

if you want to make your vim colorful just like me, I suggest you to follow two steps:

  1. learn how to turn on the feature by following this link: turn on color syntax highlighting in vi or vim.

key steps in the link:

  1. Edit ~/.vimrc file by typing the command: vi ~/.vimrc

  2. Append the following option:syntax on

  3. Save and close the file

  4. Test it by running vim command: vim foo.sh

  1. find a color scheme you like, and use it. The scheme which I use:the scheme that I am using
1
  • When using links to external source, you should check the "Provide context for links" part (Quote important parts) of the relevant part of the guide: unix.stackexchange.com/help/how-to-answer Commented Sep 3, 2018 at 6:48
0

If bash is your choice, I recommend oh-my-bash. If zsh is your choice, I recommend oh-my-zsh. Both support colorization of your terminal and different output.

0

I'd like to humbly advertise my recent publication of ta or textattr, a library and command-line tool that aims to make adding color and attributes to beautify the terminal output of your program easier by translating human-readable specs into ANSI escape codes.

For example:

echo "The Git repo $(ta yellow)${CUR_REPO}$(ta off) is $(ta green)up-to-date$(ta off)"

or the even shorter:

echo "The Git repo $(ta y)${CUR_REPO}$(ta f) is $(ta g)up-to-date$(ta f)"

or an alternate:

tawrite "The Git repo " @y ${CUR_REPO} @f " is " @g up-to-date @f "\n"

will give you something like:

enter image description here

Currently this library is usable from four languages C, C++, D and Python apart from commandline use from your favourite shell.

Note that it does not automatically colourize the output of any other programs. It is rather a utility to help you with not having to remember the abstruse codes. You only need to use the obvious colour names or their easy-to-remember rgb cmyk w(hite) (of)f abbreviations.

For more details visit the textattr repo.

0

For awesome colorization of diff you should take a look at https://github.com/dandavison/delta

You just install it and then you add this to .gitconfig

[pager] diff = delta log = delta reflog = delta show = delta [interactive] diffFilter = delta --color-only --features=interactive 

Then you get syntax highlighting in your diffs

syntax highlighted diff

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.