I have seen several answers but they all talk about echo. How can I change the color of an output of a command in bash? For instance, I want to colorize the output of hostname command.

$ hostname 
Nameofcomputer <--- Just the output to be colored and then it returns to default color of the shell.
  • How will your system decide what and how to colour? i.e. do you want to hard code specific colours into specific commands? e.g. hostname should always output red? – Sparhawk May 5 '17 at 0:11
  • 1
    FWIW I don't think it's a dupe, but it's certainly unclear IMO. – Sparhawk May 5 '17 at 0:11
  • @Sparhawk for example $ set-color red hostname , just want the outout of command to be in certain color and then the prompt returns to default color – Fenomatik May 5 '17 at 2:23
  • I would try writing functions that echo'd out the color-changing sequences, then ran command the-original-command "$@", then the end-color sequence. You might be able to make a set-color function that creates such functions on-demand as well. Beware commands (such as some greps) that may declare their own colors. – Jeff Schaller May 5 '17 at 2:45
  • I wrote up a partial answer, just as @JeffSchaller posted. It's basically the same strategy, but fails in some cases. – Sparhawk May 5 '17 at 2:46

There are programs that will already do this for you, like grc, it's a

generic colouriser, can be used to colourise logfiles, output of commands, arbitrary text.... configured via regexp's.

enter image description here

[I normally don't like to use an image of text, but I don't think StackExchange has colour fomrat options]

Or there's also source-highlight.

See Is there colorizer utility that can take command output and colorize it accordingly to pre-defined scheme? on SuperUser too


This is a partial answer that works in general, but chokes on special characters.


case $1 in
  red)     col=$'\e[1;31m' ;;
  green)   col=$'\e[1;32m' ;;
  yellow)  col=$'\e[1;33m' ;;
  blue)    col=$'\e[1;34m' ;;
  magenta) col=$'\e[1;35m' ;;
  cyan)    col=$'\e[1;36m' ;;

printf "%s" "${col}"

eval $@


Presuming it's called set-color, simply call it with set-color red hostname.


  • The case block defines the colours, as per jasonwryan's answer here.
  • The script sets this colour with printf.
  • shift removes the first option fed to the script (i.e. the colour).
  • eval $@ then executes the rest of the script.


The problem is that the script eats up the escapes and quotations marks. e.g. if you normally executed.

grep "foo bar" file\ name

Then you'd have to use

set-color red grep \"foo bar\" file\\ name
  • wouldn't quoting "$@" help? – Jeff Schaller May 5 '17 at 2:56
  • @JeffSchaller It doesn't seem to. :( – Sparhawk May 5 '17 at 6:27
tput setaf 1; hostname; tput sgr0

tput queries the terminal database for the corresponding capability. Here setaf for set ANSI colour 1 (red), sgr0 to select graphic rendition none to go back to default attributes. Instead of tput sgr0, you can also use tput op (original pair) to only reset background and foreground colour and leave other graphic attributes (bold, underline, standout, reverse...) alone.

Some shells like zsh, tcsh or fish have builtin support to query that database or map color names to ANSI codes (like zsh or fish), but not bash.

In zsh, using prompt expansion to print the hostname in red:

print -P '%F{red}%m%f'

(%f only resets the foreground colour)

In tcsh or zsh with the echotc builtin using termcap codes instead of terminfo:

echotc AF 1; hostname; echotc me

(zsh has echoti for the terminfo codes setab/sgr0 like modern versions of tput).

In zsh, the % parameter expansion flag turns on prompt expansion upon parameter expansion, so you can do:

red=%F{red} normal=%f

echo ${(%)red}whatever%{(%)normal}

In zsh, you'll also find a colors autoloadable function that you can run to have helpers to write things in colour:

autoload colors; colors

echo $fg[red]whatever$fg[default]

Not the answer you're looking for? Browse other questions tagged or ask your own question.