So how do you setup, change and pimp out Linux / UNIX shell prompt?
Most of us work with a shell prompt. By default most Linux distro displays hostname and current working directory. You can easily customize your prompt to display information important to you. You change look and feel by adding colors. In this small howto I will explain howto setup:
a] Howto customizing a bash shell to get a good looking prompt
b] Configure the appearance of the terminal.
c] Apply themes using bashish
d] Howto pimp out your shell prompt
Prompt is control via a special shell variable. You need to set PS1, PS2, PS3 and PS4 variable. If set, the value is executed as a command prior to issuing each primary prompt.
- PS1 - The value of this parameter is expanded (see PROMPTING below) and used as the primary prompt string. The default value is \s-\v\$ .
- PS2 - The value of this parameter is expanded as with PS1 and used as the secondary prompt string. The default is >
- PS3 - The value of this parameter is used as the prompt for the select command
- PS4 - The value of this parameter is expanded as with PS1 and the value is printed before each command bash displays during an execution trace. The first character of PS4 is replicated multiple times, as necessary, to indicate multiple levels of indirection. The default is +
How do I display current prompt setting?
Simply use echo command, enter:
$ echo $PS1
Output:
\\u@\h \\W]\\$
How do I modify or change the prompt?
Modifying the prompt is easy task. Just assign a new value to PS1 and hit enter key:
My old prompt --> [vivek@105r2 ~]$
PS1="touch me : "
Output: My new prompt
touch me :
So when executing interactively, bash displays the primary prompt PS1 when it is ready to read a command, and the secondary prompt PS2 when it needs more input to complete a command. Bash allows these prompt strings to be customized by inserting a number of backslash-escaped special characters that are decoded as follows:
- \a : an ASCII bell character (07)
- \d : the date in "Weekday Month Date" format (e.g., "Tue May 26")
- \D{format} : the format is passed to strftime(3) and the result is inserted into the prompt string; an empty format results in a locale-specific time representation. The braces are required
- \e : an ASCII escape character (033)
- \h : the hostname up to the first '.'
- \H : the hostname
- \j : the number of jobs currently managed by the shell
- \l : the basename of the shell’s terminal device name
- \n : newline
- \r : carriage return
- \s : the name of the shell, the basename of $0 (the portion following the final slash)
- \t : the current time in 24-hour HH:MM:SS format
- \T : the current time in 12-hour HH:MM:SS format
- \@ : the current time in 12-hour am/pm format
- \A : the current time in 24-hour HH:MM format
- \u : the username of the current user
- \v : the version of bash (e.g., 2.00)
- \V : the release of bash, version + patch level (e.g., 2.00.0)
- \w : the current working directory, with $HOME abbreviated with a tilde
- \W : the basename of the current working directory, with $HOME abbreviated with a tilde
- \! : the history number of this command
- \# : the command number of this command
- \$ : if the effective UID is 0, a #, otherwise a $
- \nnn : the character corresponding to the octal number nnn
- \\ : a backslash
- \[ : begin a sequence of non-printing characters, which could be used to embed a terminal control sequence into the prompt
- \] : end a sequence of non-printing characters
Let us try to set the prompt so that it can display today’d date and hostname:
PS1="\d \h $ "
Output:
Sat Jun 02 server $
Now setup prompt to display date/time, hostname and current directory:
$ PS1="[\d \t \u@\h:\w ] $ "
Output:
[Sat Jun 02 14:24:12 vivek@server:~ ] $
How do I add colors to my prompt?
You can change the color of your shell prompt to impress your friend or to make your own life quite easy while working at command prompt.
Putting it all together
Let us say when you login as root/superuser, you want to get visual confirmation using red color prompt. To distinguish between superuser and normal user you use last character in the prompt, if it changes from $ to #, you have superuser privileges. So let us set your prompt color to RED when you login as root, otherwise display normal prompt.
Open /etc/bashrc (Redhat and friends) / or /etc/bash.bashrc (Debian/Ubuntu) or /etc/bash.bashrc.local (Suse and others) file and append following code:
# vi /etc/bashrc
or
$ sudo gedit /etc/bashrc
Append the code as follows
# If id command returns zero, you’ve root access. if [ $(id -u) -eq 0 ]; then # you are root, set red colour prompt PS1="\\[$(tput setaf 1)\\]\\u@\\h:\\w #\\[$(tput sgr0)\\]" else # normal PS1="[\\u@\\h:\\w] $" fi
Close and save the file.
My firepower prompt
Check this out:

(click to enlarge)
You can also create complex themes for your bash shell using bashish. Bashish is a theme enviroment for text terminals. It can change colors, font, transparency and background image on a per-application basis. Additionally Bashish supports prompt changing on common shells such as bash, zsh and tcsh. Install bashish using rpm or apt-get command:
# rpm -ivh bashish*
OR
# dpkg -i bashish*
Now start bashish for installing user configuration files:
$ bashish
Next you must restart your shell by typing the following command:
$ exec bash
To configure the Bashish theme engine, run
$ bashishtheme
basish in action (screenshots from official site):
![]()
![]()
Finally, you can always use aterm or other terminal program such as rxvt. It supports nice visual effect , like transparency, tinting and much more by visiting profile menu. Select your terminal > click on Edit menu bar > Profiles > Select Profile > Click on Edit button > Select Effects tab > Select transparent background > Close
Further readings:
- Coloring your prompt with tput and shell escape code
- How-to reference guide to customizing the BASH command-line prompt.
- Download Bashish theme enviroment for text terminals.
Featured Articles:
- 20 Linux System Monitoring Tools Every SysAdmin Should Know
- 20 Linux Server Hardening Security Tips
- 10 Greatest Open Source Software Of 2009
- My 10 UNIX Command Line Mistakes
- Top 5 Email Client For Linux, Mac OS X, and Windows Users
- Top 20 OpenSSH Server Best Security Practices
- Top 10 Open Source Web-Based Project Management Software
- Top 5 Linux Video Editor Software
- Email this to a friend
- Download PDF version
- Printable version
- Comment RSS feed
- Last Updated: Oct/9/2007



{ 34 comments… read them below or add one }
LOL .. nice your command is my wish
Here’s my ZSH prompt. I start by defining a bunch of complicated variables, then actually build the prompt with a much more legible set of instructions.
# Define common and useful things to put in a prompt
typeset -A prc
prc[abbrevpath]='%{${fg[red]}%}%B%45
The result is like:
kirk@mysystem [7:54} ~
:) $
where "kirk@mysystem" is green for normal users and red for root. The time is blue. The current directory is in red, and if it's longer that a set amount, the beginning is replaced with " ... " (so that you always see bottommost directory you're in). The smiley face is ":)" in green if the last command you typed executed correctly, or ":(" in red if it didn't. "$" is black, and if you're root, it's "#" instead.
It packs a lot of useful information into a small area, like who you are, where you are, whether you're root, and whether you can make commands that succeed. If I see too many red frowns, I call it quits for the day.
I think you can do most of this in Bash, too, but I never got that creative.
Two things that I’d like to know how to do (if possible) with my bash prompt…
1) Include the full path of the current directory, but only the last 25 characters if the path is longer than that. I’d also prefer a shortened path to be preceeded by “…”.
2) Memorize the current cursor position, drop to the bottom line of the screen, output my prompt info, jump back to the previous cursor position.
Either of these possible?
how to eliminate the hostname on the konsole?
what should i add?
hey chika do this on your console
PS1=”\d $”
How to change the prompt when access is via ssh, I have tried and don’t find that setting.
Debian
@ SimpleSimon
For your first question, you want to look at the PROMPT_COMMAND variable. I don’t have an answer for your second question.
Example:
# This will limit the path to 30 characters.
PROMPT_COMMAND=’if [ ${#PWD} -gt 30 ]; then myPWD=${PWD:0:12}…${PWD:${#PWD}-15}; else myPWD=$PWD; fi’
PS1=”\u@\h \$myPWD\$ ”
HTH,
Jamie
Thank you very much
On slackware, I simply want:
/home/steve $
unless I su to root, then I want
/home/steve #
It would seem that this should do it:
if [ $(id -u) -eq 0 ];
then # you are root
PS1=”$PWD #”
else # normal
PS1=”$PWD $”
fi
but after suing to root I still get
/home/steve $
How would I fix this?
Steve, you may need to create .shrc file or whichever you’re using under root’s home directory so it gets sourced when you log in or sudo as root.
hi,
how to accept the prompt value into a variable.
x=echo $PS1 : this is not working
thanks,
Balaji
Balaji,
Use following code
Hi Vivek,
i still get an error.
bash-2.05b$ promt.ksh
$
./promt.ksh[7]: syntax error: `1′ unexpected
bash-2.05b$ cat promt.ksh
#!/bin/ksh
x=$(echo $PS1)
echo $x
exit (1)
As the error message says, the error is on line 7, which appears to be your exit command. If you want to exit with a non-zero return code, use a number without parentheses.
Dan, you were exactly right, almost. Slackware used bash for both user and root. I ended up with
export PS1=’\e[0;32m$PWD $\e[m ‘
in ~/.bashrc
and
export PS1=’\e[0;31m$PWD #\e[m ‘
in /root/.bashrc
and I not only get what I want, but I get Christmas colors, too. Thanks for the tip and this article.
@ SimpleSimon
My answer for question 1:
PS1='${PWD/????????????????????????????*/...${PWD:${#PWD}-25}} '
Note: I used 28 question marks otherwise the … could make the string longer. If you reduce it to 25 then use ${#PWD}-22 in the substring length.
Question 2, answer 1:
I have tried this out but I can’t recommend it. I would recommend anser 2 below. However it is interesting to show what can be done.
You need to look at /etc/termcap for your terminal (xterm) in my case, and at the meaning of the tcap codes in terminfo.
In particular:
sc – save cursor
rc – restore cursor
cm – cursor move
ce – clear to end of line
These can take quite a bit of understanding, but my “cm” is
\E[%i%d;%dHwhich means that in my PS1 that\e[1;1Hwould move the cursor to the top of the screen (the first number is the row). If there is no %i in the "cm" then numbers start from zero.My "sc" is
\E7My "rc" is
\E8My "ce" is
\E[KSo setting PS1 thus:
PS1='${PWD/????????????????????????????*/...${PWD:${#PWD}-25}} \e7\e[1;1H\w\e[K\e8'
Will write the current directory on the top line of the screen.
Next you need to ensure that the checkwinsize is set.
shopt -s checkwinsize
You might put it in your ".bashrc" . This sets the LINES and COLUMNS variables after every external command.
Now try setting PS1 thus:
PS1='${PWD/????????????????????????????*/...${PWD:${#PWD}-25}} \e7\e[$LINES;1H\w\e[K\e8'
This will write the directory at the bottom left. However, this is not good as using the top line. Once the screen is full, bash and program output will mangle the directory line.
Hence I recommend answer 2.
Question 2, answer 2:
Assuming that you are using a virtual terminal - you can often put the current directory (or other info) into title of the window.
I use bash on Windows/Cygwin and by default PS1 set thus:
PS1='\[\e]0;\w\a\]\n\[\e[32m\]\u@\h \[\e[33m\]\w\[\e[0m\]\n\$ '
This makes the prompt:
user@host directory
$
in pretty colours and puts the current directory in the title for the xterm or ansi console (rxvt or Windows command window). If you use another terminal emulator you may need to find other command codes that do this.
This works well except the newline in the prompt can muck up the editing of very long previous commands. However, if you use the answer to question 1 you could remove it.
PS1='\[\e]0;\w\a\]\n\[\e[32m\]\u@\h \[\e[33m\]'${PWD/????????????????????????????*/...${PWD:${#PWD}-25}}\[\e[0m\]\n\$ '
Use the csh shell … if by mistake u have moved to another shell like bash
How can I get the /home rather than ~ ?
cd /home
irvy — I think Vivek may have misunderstood you. You get the /home rather than the abbreviated ~ path by using $PWD (instead of \w or \W for instance). You shouldn’t have to precede it by \, either. There are examples above. Good luck.
Hey, I absolutely *love* the desktop background in that example. Waterfall and desert and crazy sky; pure adventure. Can you tell me where to find it or even email me a copy? Thanx!
My fully localised prompt:
export PS1="\e[01;33m# \e[01;35m\D{%A %e %B %G %R %Z} \e[00;31m\u\e[01;32m@\e[00;31m\h \e[01;33m\w :\e[00m\n"It give something like:
# lundi 8 juin 2009 20:15 CEST dom@tuxstudio ~ :The # at the beginning associated with the final newline make this prompt absolutely perfect to copy and paste stuffs.
Hey, I just customised a ubuntu liveCD without the XWindows system installed, but the bash that i’m getting has very odd looking fonts , how can i change those? please advise.
Thanks
~Salil
how to change the diectory using go function
@ QZ did you ever get a response back regarding that wonderful wallpaper image?
I’m interested in it as well! It looks great!
hii
Thank U for help
I am not getting the desired prompt. this is my .profile
PS1=”[\d \t \u@\h:\w ] $ ”
export PS1
prompt is the below one:
[d t u@h:w ] $
what is wrong I am doing here? any help appreciated.
Thanks
@ahmed
Bash treats backslash characters specially in double quoted strings. Try single quotes around the prompt specification
PS1=’[\d \t \u@\h:\w]$ ‘
I tried single quotes as below:
PS1=’[\d \t \u@\h:\w ] $ ‘
it still gives the same output:
[d t u@h:w ] $
@Ahmed:
” and ” are different characters, try replacing them using copy/paste.
My PS1 var is:
export PS1=”\u [\W] \$ “
Thanks Bob,
I tried copy pasting in my .profile, but it is getting copied as export PS1=.\u [\W] \$ .
“ is replaced by .(dot). which keystroke will type this “?
@Ahmed:
You could try copying the character from the ~/.bashrc file itself, for example at lines 5-6:
# If not running interactively, don’t do anything
[ -z "$PS1" ] && return
The double quotes look different on my side and on the site. There are “strait” quotation marks (unicode 0022) and English quotation marks (unicode 201C / 201D). The site converts the first one into the second one.
Maybe try editing the line with another text editor (nano, vi…) and/or copy the quotation marks from the same file, not from the web site.
For unicode characters, check:
http://triggertek.com/r/unicode/0020-007F
http://triggertek.com/r/unicode/2000-206F
I set PS1=”[\u@\h:\w]\$ ” in my .bashrc file, however, when I type bash at a cmd.exe window the I get
C:\utils>bash
bash: $’\r’: command not found
[david@DESKTOP:/cygdrive/c/utils]$
- the cursor is located on the [ at the start of the line rather than after the $?
- why does the $\r mean?
Any help welcomed.
Thanks.
david
my issue is that my screen size is 140 characters. Due to my PS1 config, my command line actually starts in column 23, that leaves 117 characters possible. Whenever I use AIX or Solaris, I can fill the entire line, and then go to the next line and keep going until I hit enter or some limit like 512 or something. What drives me up a wall with linux is that it can only show 25 characters, then shifts left or right. How can I get linux to display the entire command line and quit that 25 character shuffle crap.