142

Is it possible to change the colors in the command prompt for the user@computer, as well as the the current directory and command parts of the prompt display?

I've already seen something like this done by OSX users, but I don't know how to do the same thing in gnome terminal (I can only change foreground and background colors).

It'd be very useful when, for example, trying to compile programs that have errors, since long, unformatted messages make it hard to distinguish which lines are commands and which are output.

Colors in osx terminal

David Foerster
  • 36,890
  • 56
  • 97
  • 151
Luiz Rodrigo
  • 1,769

6 Answers6

174

You can edit the settings editing the file: ~/.bashrc.

  1. Open the file: gedit ~/.bashrc.

  2. Look for the line with #force_color_prompt=yes and uncomment (delete the #).

  3. Look for the line below if [ "$color_prompt" = yes ]; then that should looks like:

     PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
    

    Pay attention at the part \u@\h it is saying "user@host" and the number before it \[\033[01;32m\] indicates the color. This is what you have to change. For example, lets change the user to purple, the "@" to black and host to green. Edit the line so it looks like:

     PS1='${debian_chroot:+($debian_chroot)}\[\033[01;35m\]\u\[\033[01;30m\]@\[\033[01;32m\]\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
    

Result:
enter image description here

The colors numbers are:

0;30m black      1;30m bold black      0;90m light black
0;31m red        1;31m bold red        0;91m light red
0;32m green      1;32m bold green      0;92m light green
0;33m yellow     1;33m bold yellow     0;93m light yellow
0;34m blue       1;34m bold blue       0;94m light blue
0;35m magenta    1;35m bold magenta    0;95m light magenta
0;36m cyan       1;36m bold cyan       0;96m light cyan
0;37m white      1;37m bold white      0;97m light white

References: 1, 2.

desgua
  • 33,215
49

You can try the BashPromptGenerator. This is by far the easiest way to get a prompt like you want. I've noticed that the colors defined here may be different from your own system, but that's a small issue. With the generated code you can change the colors yourself.

Server user:

export PS1="\[\e[01;37m\][\[\e[0m\]\[\e[01;32m\]\u\[\e[0m\]\[\e[00;37m\]@\[\e[0m\]\[\e[01;34m\]\h\[\e[0m\]\[\e[00;37m\] \[\e[0m\]\[\e[00;37m\]\t\[\e[0m\]\[\e[01;37m\] \W]\\$ \[\e[0m\]"

Server root:

export PS1="\[\e[01;37m\][\[\e[0m\]\[\e[01;31m\]\u\[\e[0m\]\[\e[00;37m\]@\[\e[0m\]\[\e[01;34m\]\h\[\e[0m\]\[\e[00;37m\] \[\e[0m\]\[\e[00;37m\]\t\[\e[0m\]\[\e[01;37m\] \W]\\$ \[\e[0m\]"

And if needed you can change hostname color to reflect different type of servers.

I use different format for my local computer:

export PS1="\[\e[01;33m\]\u\[\e[0m\]\[\e[00;37m\]@\[\e[0m\]\[\e[01;36m\]\h\[\e[0m\]\[\e[00;37m\] \t \[\e[0m\]\[\e[01;35m\]\w\[\e[0m\]\[\e[01;37m\] > \[\e[0m\]"

My favorite now:

export PS1="\n\[\e[01;33m\]\u\[\e[0m\]\[\e[00;37m\]@\[\e[0m\]\[\e[01;36m\]\h\[\e[0m\]\[\e[00;37m\] \t \[\e[0m\]\[\e[01;35m\]\w\[\e[0m\]\[\e[01;37m\] \[\e[0m\]\n$ "

This last prompt has one nice touch. It adds a newline after the prompt, and an empty newline before. Now you can display the complete directory path without problem, and it makes it more clear where a new command starts, in case of long output.


Another update, as ZSH is now the default shell on Macos. This is to be edited in .zshrc:

NEWLINE=$'\n'
DATE=$( date +"[%Y-%m-%d %H:%M:%S]" )
PROMPT="${NEWLINE}%F{yellow}${DATE} %(!.%F{red}.%F{white})%n%F{cyan}@%m %F{yellow}%d${NEWLINE}%F{reset}> "
SPRBRN
  • 2,535
6

For details, see this detailed HOWTO.

In short, you can alter the prompt by editing the $PS1 environment variable. There's so much to say here, that I'll just show you my prompt and refer you to the link above for more details.

The color-related parts are in the function setPrompt:

# This function from: https://wiki.archlinux.org/index.php/Color_Bash_Prompt_%28%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9%29#Wolfman.27s
##################################################
# Fancy PWD display function
##################################################
# The home directory (HOME) is replaced with a ~
# The last pwdmaxlen characters of the PWD are displayed
# Leading partial directory names are striped off
# /home/me/stuff          -> ~/stuff               if USER=me
# /usr/share/big_dir_name -> ../share/big_dir_name if pwdmaxlen=20
##################################################
bash_prompt_shortener() {
    # How many characters of the $PWD should be kept
    local pwdmaxlen=25
    # Indicate that there has been dir truncation
    local trunc_symbol=".."
    local dir=${PWD##*/}
    pwdmaxlen=$(( ( pwdmaxlen < ${#dir} ) ? ${#dir} : pwdmaxlen ))
    NEW_PWD=${PWD/#$HOME/\~}
    local pwdoffset=$(( ${#NEW_PWD} - pwdmaxlen ))
    if [ ${pwdoffset} -gt "0" ]
    then
        NEW_PWD=${NEW_PWD:$pwdoffset:$pwdmaxlen}
        NEW_PWD=${trunc_symbol}/${NEW_PWD#*/}
    fi
}


function setPrompt {
  COLOR1="\[\033[1;33m\]"     #First color
  COLOR2="\[\033[0;33m\]"     #Second color
  NO_COLOR="\[\033[0m\]"      #Transparent - don't change

  case $TERM in 
    xterm*)
      TITLEBAR="\[\033]0;\h - \w\007\]"
      ;;
    *)
      TITLEBAR=""
      ;;
  esac

  local dash_open="${COLOR1}-${COLOR2}-"
  local dash_close="${COLOR2}-${COLOR1}-"
  local spacer="${COLOR2}-"
  local jobs_and_history="${COLOR2}(${COLOR1}\!${COLOR2}:${COLOR1}\j${COLOR2})"
  local user_host="${COLOR2}(${COLOR1}\u${COLOR2}@${COLOR1}\H${COLOR2})"
  local host="${COLOR2}(${COLOR1}\H${COLOR2})"
  local root_or_not="${COLOR2}(${COLOR1}\\\$${COLOR2})"
  local cwd="${COLOR2}(${COLOR1}\w${COLOR2})"
  #PS1="${TITLEBAR}${COLOR1}-${COLOR2}-(${COLOR1}\!${COLOR2}:${COLOR1}\j${COLOR2})-(${COLOR1}\w${COLOR2})-${COLOR1}-\n-${COLOR2}-(${COLOR1}\u${COLOR2}@${COLOR1}\H${COLOR2})-(${COLOR1}\\\$${COLOR2})-${COLOR1}- ${NO_COLOR}"
  #PS1="${TITLEBAR}${dash_open}${cwd}${spacer}${root_or_not}${dash_close}\n${dash_open}${jobs_and_history}${spacer}${host}${dash_close}${NO_COLOR} "
  #PS2="${COLOR2}--${COLOR1}- ${NO_COLOR}"
  PS1="${TITLEBAR}${COLOR1}"'${NEW_PWD}'"${COLOR2}:\$${NO_COLOR} "
  PS2="$spacer$dash_close$NO_COLOR "
}

bash_prompt_shortener
setPrompt
unset setPrompt

#Determine and display the exit Status of the last command, if non-zero.
function checkExitStatus() {
  local status="$?"
  local signal=""
  local COLOR1="\033[0;0;33m"     #First color
  local COLOR2="\033[0;0;36m"     #Second color
  local NO_COLOR="\033[0m"        #Transparent - don't change

  if [ ${status} -ne 0 -a ${status} != 128 ]; then
    # If process exited by a signal, determine name of signal.
    if [ ${status} -gt 128 ]; then
      signal="$(builtin kill -l $((${status} - 128)) 2>/dev/null)"
      if [ "$signal" ]; then
        signal="$signal"
      fi
    fi
    echo -e "${COLOR1}[Exit ${COLOR2}${status} ${signal}${COLOR1}]${NO_COLOR}" 1>&2
    #echo -ne "${COLOR1}[Exit ${COLOR2}${status}${COLOR1} ${COLOR2}${signal}${COLOR1}]${NO_COLOR} " 1>&2
    fi
  return 0
}
print_prompt_time() {
    printf "%*s\r" $(tput cols) "$(date '+%T')"
}

promptCmd() {
    checkExitStatus
    print_prompt_time
}

PROMPT_COMMAND=promptCmd

In addition to colors, my prompt has a few other features, such as abbreviated directory names (see the function bash_prompt_shortener), automatic display of the last command's exit status if nonzero (function checkExitStatus), and display of the time in the rightmost columns (function print_prompt_time).

Seth
  • 59,332
3

You can use a bash generator service. For example, I like to make it through Ezprompt. This is an example I made:

PS1="\[\e[34m\][\[\e[m\] \[\e[36m\]\A\[\e[m\] \[\e[37m\]\u\[\e[m\]\[\e[31m\]@\[\e[m\]\[\e[32m\]\h\[\e[m\] \[\e[35m\]~\[\e[m\] \[\e[34m\]]\[\e[m\]\n$ "

After getting the bash results you are satisfied with, edit your prompt by running the following export command or by editing the ~/.bashrc file with the nano text editor or vim:

sudo nano ~/.bashrc

and adding the export command:

export PS1="\[\e[34m\][\[\e[m\] \[\e[36m\]\A\[\e[m\] \[\e[37m\]\u\[\e[m\]\[\e[31m\]@\[\e[m\]\[\e[32m\]\h\[\e[m\] \[\e[35m\]~\[\e[m\] \[\e[34m\]]\[\e[m\]\n$ "
gUfriL
  • 131
  • 5
0

Update:

The answer was meanwhile corrected. I'll let this up anyway, as I like how I illustrated the connection between the colour palette and the codes. ;)

A correction for the accepted answer by @desgua :

The table is wrong. To access the colours of the second column in the table (which corresponds to the second row of the colour palette), you need numbers 90 to 97 and not 30 to 37. The latter are just for the first column in the table (first row in the palette).

Also, the first number 00 or 01 in front of the semicolon just affects whether the font is printed bold or not. 1or 01 for bold and 00, or 0 or simply nothing (and no semicolon) for normal text.

Corrected table:

Black       30     Dark Gray     90
Red         31     Light Red     91
Green       32     Light Green   92
Brown       33     Yellow        93
Blue        34     Light Blue    94
Purple      35     Light Purple  95
Cyan        36     Light Cyan    96
Light Gray  37     White         97

First row: values 30 to 37. Second row: values 90 to 97

Whether it's cyan, red, green etc., depends on the colours you've configured in the colour palette. Those numbers are just selectors for the 16 entries of the colour palette and don't encode colour information themselves.

So, in my case for example, using the default GNOME colour palette, I've configured it like this:

PS1='${debian_chroot:+($debian_chroot)}\[\033[01;94m\]\u\[\033[01;36m\]@\[\033[01;32m\]\h\[\033[00m\]:\[\033[01;94m\]\w\[\033[00m\]\$ '

[01;94m\]\u: username bold, 5th colour of second palette row (light blue)
[01;36m\]@: @ bold, 7th colour of first palette row (cyan)
[01;32m\]\h: hostname bold, third colour of first palette row (green)

Zacryon
  • 101
-2

I wrote a file that can help you customise everything

Execute the file with a leading . to make it run on the same terminal else it will create a child terminal and results thereof will not be seen. Like this:

. shortern_path_terminal.sh

How it works:

  • The variable PS1 controls the display of the terminal.

    PS1='\[\e]0;\u@\h: \w\a\]\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\W\[\033[00m\]$ '
    
    • u - Refers to the user

    • w - Refers to the current working directory

    • W - Shows the full path up to the current working directory

    • h - Displays the name of the system

    • [\033[01;32m] - Precedes the texture of text

    • 01 bold

    • 00 not bold

    • {colour}m

        Black       0;30     Dark Gray     1;30
        Blue        0;34     Light Blue    1;34
        Green       0;32     Light Green   1;32
        Cyan        0;36     Light Cyan    1;36
        Red         0;31     Light Red     1;31
        Purple      0;35     Light Purple  1;35
        Brown       0;33     Yellow        1;33
        Light Gray  0;37     White         1;37
      

Reference

Tangani
  • 1
  • 1