|
Softpanorama
(slightly skeptical)
Open Source Software Educational Society |
May the
source be with you,
but remember the KISS principle ;-)
|
BASH Prompt Control Symbols Reference
Gentoo Linux
Documentation -- Prompt magic by Daniel Robbins
|
Sequence |
Description |
| \a |
The ASCII bell character (you can also type \007) |
| \d |
Date in "Wed Sep 06" format |
| \e |
ASCII escape character (you can also type \033) |
| \h |
First part of hostname (such as "mybox") |
| \H |
Full hostname (such as "mybox.mydomain.com") |
| \j |
The number of processes you've suspended in this shell by hitting ^Z |
| \l |
The name of the shell's terminal device (such as "ttyp4") |
| \n |
Newline |
| \r |
Carriage return |
| \s |
The name of the shell executable (such as "bash") |
| \t |
Time in 24-hour format (such as "23:01:01") |
| \T |
Time in 12-hour format (such as "11:01:01") |
| \@ |
Time in 12-hour format with am/pm |
| \u |
Your username |
| \v |
Version of bash (such as 2.04) |
| \V |
Bash version, including patchlevel |
| \w |
Current working directory (such as "/home/drobbins") |
| \W |
The "basename" of the current working directory (such as "drobbins")
|
| \! |
Current command's position in the history buffer |
| \# |
Command number (this will count up at each prompt, as long as you
type something) |
| \$ |
If you are not root, inserts a "$"; if you are root, you get a "#" |
| \xxx |
Inserts an ASCII character based on three-digit number xxx (replace
unused digits with zeros, such as "\007") |
| \\ |
A backslash |
| \[ |
This sequence should appear before a sequence of characters that
don't move the cursor (like color escape sequences). This allows bash to
calculate word wrapping correctly. |
| \] |
This sequence should appear after a sequence of non-printing
characters. |
So, there you have all of bash's special backslashed escape sequences.
Play around with them for a bit to get a feel for how they work. After
you've done a little testing, it's time to add some color.
Colorization
Adding color is quite easy; the first step is to design a prompt without
color. Then, all we need to do is add special escape sequences that'll be
recognized by the terminal (rather than bash) and cause it to display
certain parts of the text in color. Standard Linux terminals and X terminals
allow you to set the foreground (text) color and the background color, and
also enable "bold" characters if so desired. We get eight colors to choose
from.
Colors are selected by adding special sequences to PS1 -- basically
sandwiching numeric values between a "\e[" (escape open-bracket) and an "m".
If we specify more than one numeric code, we separate each code with a
semicolon. Here's an example color code:
When we specify a zero as a numeric code, it tells the terminal to reset
foreground, background, and boldness settings to their default values.
You'll want to use this code at the end of your prompt, so that the text
that you type in is not colorized. Now, let's take a look at the color
codes. Check out this screenshot:
Color chart

To use this chart, find the color you'd like to use, and find the
corresponding foreground (30-37) and background (40-47) numbers. For
example, if you like green on a normal black background, the numbers are 32
and 40. Then, take your prompt definition and add the appropriate color
codes. This:
becomes:
export PS1="\e[32;40m\w> "
|
So far, so good, but it's not perfect yet. After bash prints the working
directory, we need to set the color back to normal with a "\e[0m" sequence:
export PS1="\e[32;40m\w> \e[0m"
|
This definition will give you a nice, green prompt, but we still need to
add a few finishing touches. We don't need to include the background color
setting of 40, since that sets the background to black which is the default
color anyway. Also, the green color is quite dim; we can fix this by adding
a "1" color code, which enables brighter, bold text. In addition to this
change, we need to surround all non-printing characters with special bash
escape sequences, "\[" and "\]". These sequences will tell bash that the
enclosed characters don't take up any space on the line, which will allow
word-wrapping to continue to work properly. Without them, you'll end up with
a nice-looking prompt that will mess up the screen if you happen to type in
a command that approaches the extreme right of the terminal. Here's our
final prompt:
export PS1="\[\e[32;1m\]\w> \[\e[0m\]"
|
Don't be afraid to use several colors in the same prompt, like so:
export PS1="\[\e[36;1m\]\u@\[\e[32;1m\]\H> \[\e[0m\]"
|
Xterm fun
I've shown you how to add information and color to your prompt, but you can
do even more. It's possible to add special codes to your prompt that will
cause the title bar of your X terminal (such as rxvt or aterm) to be
dynamically updated. All you need to do is add the following sequence to
your PS1 prompt:
Simply replace the substring "titlebar" with the text that you'd like to
have appear in your xterm's title bar, and you're all set! You don't need to
use static text; you can also insert bash escape sequences into your
titlebar. Check out this example, which places the username, hostname, and
current working directory in the titlebar, as well as defining a short,
bright green prompt:
export PS1="\[\e]2;\u@\H \w\a\e[32;1m\]>\[\e[0m\] "
|
This is the particular prompt that I'm using in the colortable
screenshot, above. I love this prompt, because it puts all the information
in the title bar rather than in the terminal where it limits how much can
fit on a line. By the way, make sure you surround your titlebar sequence
with "\[" and "\]", since as far as the terminal is concerned, this sequence
is non-printing. The problem with putting lots of information in the title
bar is that you will not be able to see info if you are using a
non-graphical terminal, such as the system console. To fix this, you may
want to add something like this to your .bashrc:
if [ "$TERM" = "linux" ]
then
#we're on the system console or maybe telnetting in
export PS1="\[\e[32;1m\]\u@\H > \[\e[0m\]"
else
#we're not on the console, assume an xterm
export PS1="\[\e]2;\u@\H \w\a\e[32;1m\]>\[\e[0m\] "
fi
|
This bash conditional statement will dynamically set your prompt based on
your current terminal settings. For consistency, you'll want to configure
your ~/.bash_profile so that it sources your ~/.bashrc on startup. Make sure
the following line is in your ~/.bash_profile:
This way, you'll get the same prompt setting whether you start a login or
non-login shell.
Well, there you have it. Now, have some fun and whip up some nifty
colorized prompts!
Resources
-
rxvt is a great little xterm that happens to have a good amount of
documentation related to escape sequences tucked in the "doc" directory
included in the source tarball.
-
aterm is another terminal program, based on rxvt. It supports several
nice visual features, like transparency and tinting.
-
bashish is a theme engine for all different kinds of terminals. Check
out some
great screenshots of bashish in action!
Extending the Bash Prompt
By
Giles Orr on Sat, 1999-07-31 23:00.
Terminal and xterm prompts can be created incorporating standard escape
sequences to give user name, current working directory, time and more.
Descended from the Bourne shell, Bash (Bourne Again Shell) is a GNU
product that is the standard command-line interface on most Linux
machines. It excels at interactivity, supporting command-line editing,
completion and recall. It also supports configurable prompts--most
people realize this, but may not realize how useful it can be.
Most Linux systems have a default prompt in one color (gray) that
includes your user name, the name of the machine you are working on and
your current working directory. In addition, you can display even more
information, use ANSI colors and manipulate the title bar of an xterm to
provide useful information.
Beyond looking cool, prompts are also useful for keeping track of
system information. One idea with appeal to many is the use of different
color prompts on different machines. If you have several xterms open on
different machines or if you tend to forget which machine you are
working on, you'll find this a great reminder.
To change your prompt, you need a basic understanding of shell
programming and UNIX utilities. The more you know, the more complex the
prompts you will be able to create.
The appearance of the prompt is governed by the shell variable PS1.
Command continuations are indicated by the PS2 string, which can
be modified in exactly the same way. Since controlling it is exactly the
same, I'll mostly be modifying the PS1 string. (PS3 and
PS4 strings are also available, but are never seen by the average
user. See the Bash man page if you're interested in their purpose.) To
change the way the prompt appears, change the PS1 variable. For
experimentation purposes, the PS1 string can be entered at the
prompt to show the results immediately. Doing so affects only your
current session. If you want to make a permanent change, modify the ~/.bashrc
file by adding the new definition of PS1. If you have root
permission, you can modify the PS1= line in the /etc/profile
file. On some distributions (Red Hat 5.1 at least), the /etc/bashrc file
overrides the /etc/profile setting of PS1 and PS2.
My default prompt includes my user name ``giles'', the name of my
work machine ``nikola'' and my home directory /home/giles. The simplest
prompt is a single character. I can change my default prompt to a simple
$ by typing:
[giles@nikola giles]$ PS1="$ "
I use the quotes to force a space after the prompt, making it more
readable.
Escape Sequences
Bash 2.02 Man Page
Many escape sequences are offered by the Bash shell for insertion in
the prompt. See the sidebar which shows the Bash 2.02 man page.
$ PS1="\u@\h \W> "<\n>
giles@nikola giles>
This example creates a prompt that is close to the default on most
Linux distributions. I wanted a slightly different appearance, so I
changed it to include the time by typing:
giles@nikola giles> PS1="[ ][\u@\h:\w]$ "<\n>
[21:52:01][giles@nikola:~]$
Bash also provides an environment variable called PROMPT_COMMAND.
The contents of this variable are executed as a regular Bash command
just before Bash displays a prompt.
[21:55:01][giles@nikola:~] PS1="[\u@\h:\w]$ "<\n>
[giles@nikola:~] PROMPT_COMMAND="date +%H%M"
2155
[giles@nikola:~] ls
bin mail
2156
[giles@nikola:~]$ unset PROMPT_COMMAND
[giles@nikola:~]
In this example, I changed PS1 by eliminating the escape
sequence, so that time was no longer a part of the prompt. Then I used
date +%H%M to display the time in a format I like better. At the
end, I used the unset command to remove
the PROMPT_COMMAND environment variable.
External Commands
As I discuss the use of external commands in prompts, I'll use the
$(command) convention for command substitution; that is,
$(date +%H%M)
means ``substitute the output from the date +%H%M command
here.'' This works in Bash 1.14.7 and 2.0+. In some older versions of
Bash, you may need to use backquotes (`date +%H%M`). Backquotes
can be used in Bash 2.0+ but are being phased out in favor of $(),
which nests better. If you are using an earlier version of Bash,
substitute backquotes wherever you see $(). If the command
substitution is escaped (i.e., \$(command) ), then use
backslashes to escape BOTH your backquotes (i.e., \`command\`).
You don't want to insert much material from an external command into
the prompt, as a prompt of great length may be created. You also want to
use a fast command, because it will be executed each time your prompt
appears on the screen. Delays in the appearance of the prompt while you
are working can be annoying.
[giles@nikola:~]$ PS1="[\$(date +%H%M)][\u@\h:\w]$ "[2159][giles@nikola:~]$
Note the backslash before the dollar sign of the command
substitution. Without it, the external command is executed exactly once:
when the PS1 string is read into the environment. For this
prompt, it would display the same time no matter how long the prompt was
used. The backslash prevents immediate shell interpretation of the
command, so date is called each time a
prompt is generated.
Shell Scripts
Linux comes with many small utility programs such as
date, grep
and wc which allow you to manipulate
data. If you wish to create complex combinations of these programs
within a prompt, it may be easier to make a shell script and call it
from the prompt. An example of a small shell script used within a prompt
is given in Listing 1.
Listing 1. Shell Script for Use in Prompt
I keep this as a shell script in my ~/bin directory, which is in my
path. Use it in a prompt in this way:
[2203][giles@nikola:~]$ PS1="[\u@\h:\w (\$(lsbytesum) Mb)]\$ "[giles@nikola:~ (0 Mb)]$ cd /bin
[giles@nikola:/bin (4.498 Mb)]$
Non-Printing Escape Sequence
Non-printing escape sequences can be used to produce interesting
effects in prompts. to use these escape sequences, you need to enclose
them in \[ and \], telling bash to ignore this material while
calculating the size of the prompt. failing to include these delimiters
results in line editing code placing the cursor in the wrong place,
because it doesn't know the actual size of the prompt. escape sequences
must also be preceded by \033[ in bash prior to version 2 or by either
\033[ or \e[ in later versions.
xterm title bar
this example modifies the title bar of an xterm window. if you try to
change the title bar of an xterm with your prompt when you are at the
console, you'll produce garbage in your prompt. to avoid this problem,
test the term environment variable to determine if your prompt is
going to be in an xterm. if the shell is an xterm, the shell variable (${titlebar})
is defined. it consists of the appropriate escape sequences, and
\u@\h:\w, which puts user@machine:working
directory in the xterm title bar. this is particularity
useful with minimized xterms, making them more rapidly identifiable. the
other material in this prompt should be familiar from previous prompts
we've created.
listing 2. Function to Set Titlebar
Listing 2 is a function that can be incorporated into ~/.bashrc. The
function name can then be called to execute the function. The function,
like the PS1 string, is stored in the environment. Once the
PS1 string is set by the function, you can remove the function from
the environment by typing unset proml. Since the prompt can't
change from being in an xterm to being at the console, the TERM
variable isn't tested each time the prompt is generated.
I used continuation markers (backslashes) in the definition of the
prompt to allow it to be continued on multiple lines. This improves
readability, making it easier to modify and debug.
I define this as a function because this is how the Bash Prompt
package deals with prompts: it is not the only way to do it, but it
works well. As the prompts you use become more complex, it becomes more
and more cumbersome to type them in at the prompt and more practical to
create them in a text file. To test this example at the prompt, save the
function as a text file called ``proml''. The Bash
source command can be used to read the prompt function by
typing:
[giles@nikola:~ (0 Mb)]$ source proml
To execute the prompt function, type:
[giles@nikola:~ (0 Mb)]$ proml
Color Text
As mentioned before, non-printing escape sequences must be enclosed
in \[\033[ and \]. For color escape sequences, they must also be
followed by a lowercase m. To include blue text in the prompt:
PS1="\[\033[34m\][\$(date +%H%M)][\u@\h:\w]$
"
The blue color that starts with the 34 color code is never switched
back to the regular gray, so any text you type after the prompt is still
in the color of the prompt. This is also a dark shade of blue (very hard
to read), so combining it with the bold code might help:
PS1="\[\033[1;34m\][\$(date +%H%M)][\u@\h:\w]$\[\033[0;37m\] "
The prompt is now in light blue, and it ends by switching the color
back to gray, which is the color most of us expect when we type.
Bash Color Equivalences
Background colors can be set by using 44 for Blue background, 41 for
a Red background, etc. No bold background colors are available.
Combinations can be used, e.g., Light Red text on a Blue background:
\[\033[44;1;31m\]. Other codes available include 4 for Underscore, 5
for Blink, 7 for Inverse and 8 for Concealed.
Listing 3. elite Function
The prompt I use most of the time is based on one called ``elite2''
in the Bash Prompt package, which I have modified to work better on a
standard console (Listing 2). (The original uses special xterm fonts.) I
define the colors as temporary shell variables for the sake of
readability--it is easier to work with. The GRAD1 variable is a
check to determine what terminal you are on, and it needs to be done
only once. The prompt you see looks like Figure 1.
The Bash Prompt package is available in beta at http://bash.current.nu/
and is the work of several people, co-ordinated by Rob Current. The
package offers a simple way to use multiple prompts or ``themes''.
Several of these prompts use the extended VGA character set, so they
look bad unless used with special xterm fonts. The ``fire'' theme shown
in Figure 2 requires these fonts. See
Stumpy's ANSI Fonts page at http://home.earthlink.net/~us5zahns/enl/ansifont.html
for instructions on installing and using these fonts.
You can change the prompt in your current terminal using the example
elite function by typing source elite (assuming the elite
function file is in your path) followed by elite. This leaves you
with an extra function (elite) in your environment space--if you want to
clean up the environment, type unset elite.
This would seem like an ideal candidate for a small shell script, but
a script doesn't work here because a script cannot change the
environment of your current shell--it can change only the environment of
the subshell it runs in. Environment variables of your current shell can
be changed by environment functions. The Bash Prompt package puts a
function called callbashprompt into
your environment, and while they don't document it, it can be called to
load any Bash Prompt theme on the fly. It looks in the theme directory
it installed, sources the function you requested, loads it, then unsets
the function. callbashprompt wasn't
intended to be used this way and has no error checking, but it works
quite well.
Resources
Configuring Bash
David Blackman
1 Introduction
Welcome to the world of Bash. Bash is probably the most widely used shell in
Linux. Bash is surprisingly configurable, hopefully, by the time you finish
reading this, you'll have an environment that is more comfortable for you.
Bash does not differentiate between internal shell variables and external
environment variables. A shell variable is a variable (usually all caps), that
is associated with a value, and is carried around between shells. Many programs
use their own variables, like PILOTRATE, which they check. Bash has it's own
variables, like MAIL, that are important to it. To set environment variables
export VAR=VALUE
or
VAR=VALUE
export VAR
To check the value of an environment variable type echo $VAR, or to
see all set variables, type env
Bash executes your ~/.bash_profile for login shell (on the console), and ~/.bashrc
for non-login shells (xterms and the like). Often you may just want to symlink
one to the other. If you export a variable, or alias something from the command
line, it only stays active for that one bash session. You must put it in your
login script for it to stick.
If you start having a monolithic .bashrc file and want better organization
you can split it up. Often times people break up thier .bashrc into aliases,
variables, functions, and the .bashrc which simply executes the others. To have
your .bashrc execute other files put in
source FILE
2 The Prompt
The first environment variable we'll learn about is PS1. PS1 stores a
character string that is interpreted by bash to create your prompt. here is a
sample PS1, and what it generate
PS1=``<\u@\h:\w>$''
<blackmad@moomintroll:/etc>
in the PS1 variable, backslashed characters get interpretted, while other
characters are displayed verbatim. \u is translated to my username, \h is
translated to my hostname up to the first period, and \w is my working
directory. Here are some of the most important backslashed characters, these can
also be found in the bash manpage, in the section PS1.
-
- \d the date in ``Weekday Month Date'' format
-
- \h the hostname up to the first `.'
-
- \H the hostname
-
- \n newline
-
- \s the name of the shell, the basename of $0
-
- \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
-
- \u the username of the current user
-
- \w the current working directory
-
- \! the history number of this command
-
- \# the command number of this command
-
- \$ if the effective UID is 0, a #, otherwise a
-
- \W the basename of the current working directory
3 Cool Xterm Title Thingy
One of the cool things in all X terminal emulatros (xterm, rxvt, Eterm ...)
is that if you print ``\033]0;STRING_HERE\007'', the title of the term changes
to STRING_HERE (try it echo -n ``\033]0;Be Happy\007'').
What I do with this is put a small function in my .bashrc
function xtitle
{
case $TERM in
xterm* | rxvt*)
local TITLEBAR='\[\033]0;\u@\h:\w\007\]'
;;
*)
local TITLEBAR=''
;;
esac
export PS1=$PS1$TITLEBAR
}
and I call this after I've set my PS1 variable, so at the end of my .bashrc I
have
PS1=''<\u@\h:\w>$''
xtitle
export PS1
which mean that if I'm in a terminal emulator, it will set TITLEBAR a string
which will print user@hostname:directory, appends that to my prompt string (so
it's printed everytime I get a new prompt), and then export that. (Note: If your
terminal emulator sets $TERM to something other then xterm* or rxvt*, just add
another case, with | WEIRD_TERM_ENV on the line with xterm* | rxvt*) before the
close paren.
4 Aliases
One of the most useful things to use with bash is aliases. Aliases are simply
making bash interpret a text string as something else. So that when you type
``happy'', bash interprets it as ``echo I'm a shiny happy shell''. All aliases
take the same form:
alias ALIAS=``COMMAND''
often you may want to change the default behavior of a command, such as ls. I
use
alias ls=``ls -aF --color''
Don't worry, there are no problems with recursive aliases. so ls now prints
all files, in color, with classiciation. \ls will execute the unaliased command.
Other time syou may decided to define a whole new command, to shorten the
amount of repetitive typing. Here are a few that I use.
alias mkall=``./configure && make && sudo make install''
alias whizz=``ssh whizziwig@www.whizziwig.com''
alias tgz=``tar -xvzf'' alias ll=''ls -aFl'' alias ls-d=''ls -Sc''
these all save time and keystrokes, and don't worry, anything you type after
the alias is still passed to it, bash will just translate the part that aliased.
so in my case, executing tgz linux-2.2.14.tar.gz, actaully executes tar -xvzf
linux-2.2.14.tar.gz
5 Mail
The $MAIL variable specifies what mailbox you want bash to poll for new mail.
You generally want to set this to your inbox. I use procmail, so I've got a lot
of mail folders, but my inbox (where mail that's actually address to em gets
sent) is /home/blackmad/Mail/inbox, so when I get new email there bash tells me
You have mail in /home/blackmad/Mail/inbox
6 PATH
The PATH variable determines where (and in what order) bash will look for
executables. Each directory is seperated by a :. Bash looks in you path from
right to left, Let's say your PATH is ''/usr/bin:/bin/:/sbin/:/sbin/''. When you
enter a command, bash will first look in it's internal shell functions, then /usr/bin,
then /bin, and so on, until it either finds the command or gets to the end of
your PATH. Often you may simply want to append or prefix you current PATH, you
can do this like so:
PATH=''$PATH:/next/path:/next_next/path''
or
PATH=''/prev/path:$PATH:/next/path''
export PATH
in the first example bash will look through /next/path and /next_next/path
after it finishes with your current PATH. in the secodn example, bashw ill first
look in /prev/path. Often You'll want to prefix your PATH with /usr/local/bin,
since that where hand compiled stuff usually goes, which is generally more
recent then what came with your distro. You may also want to prefix ~/bin, and
have a bin directory in your homedir where you can put your customized versions
of programs and scripts (useful if you dont have root on the box).
7 The last step
Since bash just runs through your bashrc and executes everything in it, you
can toss in programs you want to run each time you login. At the end of many
users bashrc's are a few commands they want executed.
mesg y
fortune
users
So whenever I log in, fortune greets me with a bit of wisdom, I turn on
messgaes, and I find out who's logged into the systems.
Copyright © 1996-2008 by Dr. Nikolai Bezroukov.
www.softpanorama.org was
created as a service to the UN Sustainable Development Networking Programme (SDNP)
in the author free time.
Submit
comments This document is an industrial compilation designed and created
exclusively for educational use and is placed under the copyright of the
Open Content License(OPL).
Original materials copyright belong to respective owners. Quotes are made
for educational purposes only in compliance with the fair use doctrine.
Standard disclaimer: The statements, views and opinions presented on
this web page are those of the author and are not endorsed by, nor do they necessarily
reflect, the opinions of the author present and former employers, SDNP or any other
organization the author may be associated with. We do not warrant the correctness
of the information provided or its fitness for any purpose.
Last modified:
February 28, 2008