Jun 2007
In a recent text configuring colors for the Bash prompt was discussed. In this
text
a method of messing with the prompt is expanded upon by actually
inserting a shell code function inline with
the bash prompt.
The bash prompt has built in commands that use escape character syntax.
By default a lot of packages ship bash with a default that shows the hostname
and relative path. The escape sequences for all users is usually kept in
/etc/bashrc or a similar system location. The sequences
themselves might look something like this:
PS1="[\u@\h:\w]\$
The above settings would look like:
[username@hostname:current_working_directory]$
Or a real example:
[jrf@vela:~/www/systhread.net/texts]$
The Bash Prompt HOWTO is a great resource for looking at different things that can be done with a prompt. Here are the escape sequences per the Bash man page that can be used:
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 cus
tomized 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")
\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
\u the username of the current user
\v the version of bash (e.g., 2.00)
\V the release of bash, version + patchlevel
(e.g., 2.00.0)
\w the current working directory
\W the basename of the current working direcĀ
tory
\! 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 con
trol sequence into the prompt
\] end a sequence of non-printing characters
Basic escape sequences are pretty nice and Bash is feature rich with them. For example look at the three different time formats:
\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
Just by default the bash prompt can be very informative but what if something a little bit more is needed?
As noted in the Bash Prompt HOWTO
commands can be executed every time the RETURN sequence is
sent to the shell interpreter. For this example the Bash Prompt HOWTO
provides ample demonstration of some commands:
#!/bin/bash
# lsbytesum - sum the number of bytes in a directory listing
TotalBytes=0
for Bytes in $(ls -l | grep "^-" | awk '{ print $5 }')
do
let TotalBytes=$TotalBytes+$Bytes
done
TotalMeg=$(echo -e "scale=3 \n$TotalBytes/1048576 \nquit" | bc)
echo -n "$TotalMeg"
will yield the results in the author's directory of:
[2158][giles@nikola:~]$ PS1="[\u@\h:\w (\$(lsbytesum) Mb)]\$ " [giles@nikola:~ (0 Mb)]$ cd /bin [giles@nikola:/bin (4.498 Mb)]$
Pretty neat stuff. The bashrc can also contain functions
that are used in the prompt itself.
XTermsbashrc
Entire functions can be put right into the .bashrc file for
similar command processing. Following is an example function:
rand_titles ()
{
if [ $TERM = xterm ]; then
TLINES=`wc -l $HOME/.xterm_titles | awk '{print $1;}'`
TLINE=$[ ${RANDOM} % $TLINES ];
TLINE=$[$TLINE + 1];
TITLE=`head -$TLINE < $HOME/.xterm_titles | tail -1`
echo -ne "\033]0;${TITLE}\007"
fi
}
.xterm_titles
file.RANDOM environment variable to calculate
a random number within the TLINES range.
Assign said number directly to TLINE TLINE.TLINE extract a line from
.xterm_titles and assign it to
TITLE.TITLE
variable).
Essentially rand_titles just picks a random line out of
a file and feeds to the current xterm program as a new
title.
Not as difficult as it would seem; the call is just slid right into the prompt command itself:
PROMPT_COMMAND='rand_titles'
Essentially - any Unix software that can receive data from a pipe can be affected by bash prompt functions.
The text would be remiss no credit was given where due. I originally
figured all of this out by downloading Carsten Haitzler's
(aka Rasterman) files section [2]. Ironically the example used was for the Z shell zsh
[ 3 ] so there was a little translating going on.
Be Warned! messing with the prompt, especially if you are inserting entire functions into it can be dangerous. If you do not have administrator access (as root or some delegated role) to the system then there are a few things to consider.
Often, power users are allowed to request test accounts. If playing with functions built into prompts is on the agenda then do so. Get a test account that can be switch-user'd to for testing.
bashrc
One of the nice things about bash is that the bashrc can be
resourced on the fly for testing. Basically take the following steps to
make sure that the original bashrc can be restored in case
of a mistake:
cd $HOMEcp .bashrc .bashrc.ORIG
Changes can be experimented with by simply sourcing the changed
bashrc:
source .bashrc
Note that a current bashrc can also just be copied to a new one,
then source the test bashrc to see if there are
any problems:
cp .bashrc bashtest (makemany changes...) source bashtest... ... pray2 $DEITY
Test functions before inclusion in the prompt. If a system has a lot of
NFS mounts then do not include a global df
command in the prompt
[5]. Keep things like how much will this cost and
can it hang?
in mind when dealing with prompt commands.
Customizing and mastering the Unix shell environment can make for not just a pleasant experience as a user but a practical experience for users.
zsh has given me
serious reason to think about trading off shells for awhile even
just for fun.df
output in every user's login files.(based on last 2 months log reports)