Customizing the Terminal: The Prompt

Written by BinnyVA on March 10, 2009 – 11:34 pm -

Terminal

Most Linux ‘gurus’ spend a lot of time working in the terminal. If you belong to that group, this post is for you. This is a tutorial to configure the terminal prompt to the best possible value for your use. Note: This tutorial is for bash users – these instructions will not work in other shells.

The Prompt

You must have seen the prompt if you have use the terminal – it is the first few characters in each line. Usually, it will be…

[username@localhost] ~ $

In this case, the user is shown three piece of information in the prompt –

  • Username of the current user
  • Hostname
  • Current folder name

This post will show you how to customize this prompt to your needs.

Editing the Prompt

Editing the prompt is very simple – you just have to edit a shell variable. To see the current prompt’s value, open a shell and type the command…

echo $PS1

The result will be something like this(in Ubuntu)…

binnyva@binlap:~$ echo $PS1
\[\e]0;\u@\h: \w\a\]${debian_chroot:+($debian_chroot)}\u@\h:\w\$

Which is functionally the same as…

\u@\h:\W\$ 

To edit this variable, run the command…

export PS1=<New Prompt Value>

Most desktop systems don’t need the username and hostname in the prompt – this is only relevent if your are connected to a remote system. So the first thing to do, if you are on a desktop system, is to remove those two. To do that, run the command…

export PS1="[\W]\$ "

This will change the prompt in the current terminal. To make it permanent, edit the ~/.bashrc and set the PS1 variable there. Just add this line at the end of the file…

export PS1="[\W]\$ "

A Better Prompt

Currently, the prompt has the basename of the current working directory. That is, if we are in ‘~/Sites/Lindesk/posts’, the prompt will be ‘[posts]$ ‘. This is good enough for most people. But I have a problem with this. If I go to another folder, say, ‘~/Sites/OpenJS/posts’, the prompt is still ‘[posts]$ ‘. The prompt is a bit ambiguous in this case. This can be done using a different character – in this case \w(small ‘w’ – the default was capital ‘W’).

[posts]$ export PS1="[\w]$ "
[~/Sites/OpenJS/posts]$ _

This is nice – but you will have a problem if the directory you are in is several levels deep. It might be something like this…

[/var/www/html/sites/Lindesk/lindesk.com/wp-content/plugins/eventr/langs]$ _

That’s long – and inconvenient. There are better ways of doing this.

Show the Beginning and the End.

A better way of doing this is to cut of a part of the folder – so the above path will look something like…

[/var/www/html.../eventr/langs] $ _

This option will show the first 15 characters of the path and then the last 15 characters – if the directory path is bigger than 30 characters. To enable this mode, open up the file ~/.bashrc and add this code…

PROMPT_COMMAND='DIR=`pwd|sed -e "s!$HOME!~!"`; if [ ${#DIR} -gt 30 ]; then CurDir=${DIR:0:12}...${DIR:${#DIR}-15}; else CurDir=$DIR; fi'
PS1="[\$CurDir] \$ "

The First Character of Each Directory

There is yet another method – I got this idea from the fish shell. In this approach, the big path will appear as…

[/v/w/h/s/L/l/w/p/e/langs] $ _

In this option, only the first character of each parent folder will be shown. Only the base folder name will be shown entirely. This is the approach I use. If you want to use this, open the ~/.bashrc file and add this…

PROMPT_COMMAND='CurDir=`pwd|sed -e "s!$HOME!~!"|sed -re "s!([^/])[^/]+/!\1/!g"`'
PS1="[\$CurDir] \$ "

Prompt Variables

The other values you can insert into the prompt are…

\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

del.icio.us | Digg it | reddit | StumbleUpon