One of my favorite Mac OS X Terminal tips involves adding the last running process into the terminal title using the following code in your .bashrc.

trap 'printf "\033]0;  `history 1 | cut -b8-`  \007"' DEBUG

Now I'm looking to customize my Bash prompt from the default into something more functional. What are some useful shell prompt examples?

locked by Mark Henderson Apr 9 '12 at 20:28

This question exists because it has historical significance, but it is not considered a good, on-topic question for this site, so please do not use it as evidence that you can ask similar questions here. This question and its answers are frozen and cannot be changed. More info: help center.

14 Answers 14

up vote 6 down vote accepted

I use a simple two-liner:




if root. People look at me like I'm crazy for using a two-line prompt, but I hate only seeing the last part of the current path, and I work with paths that are too long to put the whole thing on the same line as the input area.

  • So I must be frakin insane for using a 3 line prompt, lol. – Ivan May 5 '09 at 18:20

I have a script ~/bin/setprompt that is executed by my .bashrc, which contains:

SELECT="if [ \$? = 0 ]; then echo \"${SMILEY}\"; else echo \"${FROWNY}\"; fi"

# Throw it all together 

This script sets the prompt to the host name followed by :) if the last command was successful and :( if the last command failed.

This, however, is the most awesomest one I've ever seen:

PS1='\[\033[0m\]\[\033[0;31m\].:\[\033[0m\]\[\033[1;30m\][\[\033[0m\]\[\033[0;28m\]Managing \033[1;31m\]\j\[\033[0m\]\[\033[1;30m\]/\[\033[0m\]\[\033[1;31m\]$(ps ax | wc -l | tr -d '\'' '\'')\[\033[0m\]\[\033[1;30m\] \[\033[0m\]\[\033[0;28m\]jobs.\[\033[0m\]\[\033[1;30m\]] [\[\033[0m\]\[\033[0;28m\]CPU Load: \[\033[0m\]\[\033[1;31m\]$(temp=$(cat /proc/loadavg) && echo ${temp%% *}) \[\033[0m\]\[\033[0;28m\]Uptime: \[\033[0m\]\[\033[1;31m\]$(temp=$(cat /proc/uptime) && upSec=${temp%%.*} ; let secs=$((${upSec}%60)) ; let mins=$((${upSec}/60%60)) ; let hours=$((${upSec}/3600%24)) ; let days=$((${upSec}/86400)) ; if [ ${days} -ne 0 ]; then echo -n ${days}d; fi ; echo -n ${hours}h${mins}m)\[\033[0m\]\[\033[1;30m\]]\[\033[0m\]\[\033[0;31m\]:.\n\[\033[0m\]\[\033[0;31m\].:\[\033[0m\]\[\033[1;30m\][\[\033[0m\]\[\033[1;31m\]$(ls -l | grep "^-" | wc -l | tr -d " ") \[\033[0m\]\[\033[0;28m\]files using \[\033[0m\]\[\033[1;31m\]$(ls --si -s | head -1 | awk '\''{print $2}'\'')\[\033[0m\]\[\033[1;30m\]] [\[\033[0m\]\[\033[1;31m\]\u\[\033[0m\]\[\033[0;31m\]@\[\033[0m\]\[\033[1;31m\]\h \[\033[0m\]\[\033[1;34m\]\w\[\033[0m\]\[\033[1;30m\]]\[\033[0m\]\[\033[0;31m\]:.\n\[\033[0m\]\[\033[0;31m\].:\[\033[0m\]\[\033[1;30m\][\[\033[0m\]\[\033[1;31m\]\t\[\033[0m\]\[\033[1;30m\]]\[\033[0m\]\[\033[0;31m\]:. \[\033[0m\]\[\033[1;37m\]$ \[\033[0m\]'

Give it a shot. It gives good information, but it will actually cause the load on your boxes to increase just by hitting enter at a prompt!

  • 1
    hah, very impressive! – Dave K May 5 '09 at 19:39
  • Looks good, but doesn't work on my freebsd box :( – Eugene Yarmash Mar 22 '10 at 12:24
  • @eugene y: Some of those paths are probably not on FreeBSD boxes... – Glen Solsberry Mar 22 '10 at 13:51
  • Scary looking, but impressive! – siliconpi Jan 26 '11 at 2:20

I'm a fan of the default Cygwin bash prompt:

PS1='\[\e]0;\w\a\]\n\[\e[32m\]\u@\h \[\e[33m\]\w\[\e[0m\]\n\$ '

or without colors:

PS1='\n\u@\h \n\$ '

looks like:

$ ls -l

I like including the time in mine. Gives me sort of a built in time around my commands:

PS1="[\t \u@\h:\w]$ "

Though after seeing a few of these, it makes me want to make mine a little smarter!

Here's mine (scroll to the right to see more interesting bit):

'-------------------------------------------------------------------------------\n${debian_chroot:+($debian_chroot)}[\w]\n\u@\h\[\033[1;33m\]\[\033[0m\]($(__git_ps1 "%s")$(parse_git_dirty))$ 

Here's the result:


When I'm inside a Git repository:


I choose to use multiple line breaks and the "horizontal ruler" to make it easier to scan buffers, and so long path names don't push the cursor too far to the right.

In ksh:

In my .profile, I set the following var (so this var is only set once per session ever, no matter how many 'su's I do:


In my .kshrc I have:

if let "${SPID:-0} != $$"; then

I become root with the following alias, rather than "su" (kroot is a root user with a ksh shell instead of sh (solaris) or bash (linux):

alias root='PCH=\# su -m kroot'
alias me="PCH=\> su -m $USER"

I have also defined these two functions:

function lprompt {
  PS1=$HOST' $? $PWD '"$PCHS "
function sprompt {
  PS1='$?":"${PWD##*/}'"$PCHS "

and finally at the end of .kshrc I have:


All of this gives me by default automatic setting of the end of my prompt to indicate whether or not I am root (and in turn if I have a parent that was root), current working directory, hostname, and exit status of last process. sprompt drops the hostname, shrinks the path down to only the basename, and removes spaces:

g3 0 /home/jj33 > expr 1 / 0
expr: division by zero
g3 2 /home/jj33 > expr 1 / 1
g3 0 /home/jj33 > root
g3 0 /home/jj33 ># me
g3 0 /home/jj33 >#> ^D
g3 0 /home/jj33 ># sprompt
0:jj33># me
g3 0 /home/jj33 >#> sprompt
0:jj33>#>expr 1 / 0
expr: division by zero

The root/me aliases are bourne from pre-sudo administration on Solaris and old habits have died hard. I doubt anyone would implement the exact same thing these days. The prompt-changing functions and the exist status continue to be very valuable to me.

I have a prompt that is simple, but uses colors to give some extra info:


The color of the hostname (drewble, in this case) is different on each machine - when I get a new machine that I work on, I choose an arbitrary color for that machine. That way, when I have a lot of terminals open, it's easy to tell which machine they're SSHed into and reduces mistakes I make by being on the wrong machine. Additionally, when I do sudo -s, I put the hostname in all caps and color the colon red, again, this reduces mistakes by making it clear you're acting as root. The path (my home directory, ~ in this case) is in bright green, which helps separate lines of output; if something creates a lot of output, it's easy to scroll up and see where the output started.

# Color the hostname
HOSTNAME=`hostname|sed -e 's/\..*$//'`
if [ $HOSTNAME = 'Caligula' ] || [ $HOSTNAME = 'Caligula.local' ]; then
    export HOST_COLOR="\[\033[1;35m\]"
if [ $HOSTNAME = 'drewble' ]; then
    export HOST_COLOR="\[\033[1;34m\]"
if [ $HOSTNAME = 'davinci' ]; then
    export HOST_COLOR="\[\033[1;31m\]"

# Color the colon red & capitalize hostname if root
if [ ${UID} -eq 0 ]; then
if [ ${UID} -eq 0 ]; then
    HOSTNAME="`echo $HOSTNAME|tr '[a-z]' '[A-Z]'`"

# Set the actual prompt
PS1=`echo -ne "$HOST_COLOR$HOSTNAME\[\033[00m\]\[\e[$COLON_COLOR\]:\[\033[01;32m\]\w\[\033[00m\]\\[\033[01;33m\]\$\[\033[00m\] "`

It isn't a shell prompt, but it is a customization that might fit the spirit of what you are asking.

I set the following environment variable:

if [ -z "$PROMPT_COMMAND" ]; then
    export PROMPT_COMMAND='history -a'
    export PROMPT_COMMAND="history -a;$PROMPT_COMMAND"

This way, if I have multiple terminals open via screen or whatever, I won't lose history when they clobber each others changes.

  export PS1="\[`if [[ $? = 0 ]]; then echo '\e[32m\h\e[0m'; else echo '\e[31m\h\e[0m' ; fi`:\w\n$ "

This displays:


With 'hostname' in green if the last executed command return code was '0' and red if it was > '0'.

Similar to chaos's answer, I kind of like


which gives me


By including the user/host on the first line, I can easily copy that entire path line when I am using SCP, or rsync to send some files to that directory.

  • Excellent idea. I can see having the complete scp path being very useful. The second line might be improved by adding the time like gms8994 suggested. – Dave K May 5 '09 at 18:51

For bash I like

PS1="\h \d \t \w\n\u > "

which results in:

myserver Mon Sep 07 07:43:11 /u08
root >

So you get hostname, date and time, full path, and then username on a new line, with the prompt. That is to minimize line wrap deep in directories. I'm in and out of boxes all day, so all I can do to keep it straight is good. I also have putty set to log everything. I can go back and look at logs, and see exactly what I was doing when. Also handy for figuring out sequences of events in several terminal windows at once.

My normal prompt is

\u@\h $PWD $WINDOW [$?] \$

This gives me the current user, current host current directory (without replacing $HOME with ~), current screen window and last error return. Since I normally have 16 or more screen windows open, knowing the current one is useful.

My zsh prompt:

[andrew@hostname ~]%

Normally, it's red and white with the current directory in pink. If root then it's darker grey with the hostname in red. If $? isn't 0 then the final % is shown in red.

function precmd {


   if [ $UID -eq 0 ]; then
       MYPROMPT="$(print '%{\e[1;30m%}[%{\e[0m%}')$(print '%{\e[1;31m%}%n%{\e[0m%}')@$(print '%{\e[1;31m%}%m%{\e[0m%}') $(print '%{\e[1;35m%}%3c%{\e[0m%}')$(print '%{\e[1;30m%}]%{\e[0m%}')"
       MYPROMPT="[$(print '%{\e[1;31m%}%n%{\e[0m%}')@%m $(print '%{\e[1;35m%}%3c%{\e[0m%}')]"

   if [ $ERR -ne 0 ]; then
       ERROR="$(print '%{\e[1;31m%}%#%{\e[0m%}') "
       export PS1=$MYPROMPT$ERROR
       export PS1="$MYPROMPT%# "

   export RPS1=""

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