Sensible Open Source

MAC OS X : BASH Customize Your Terminal Prompt; A little Color, Invoke A Script & Other Prompt Options

posted 12 February 2006, Sunday
Ever go into the MAC OS X Terminal?  Do you have BASH? If you don't and need a tutorial on BASH try this link!

Now, if you are new to BASH or have experience with BASH the PROMPT is very useful for information that can be conveyed to the user about the date/time, login id, jobs running and several other options.  Furthermore, the prompt can be set to display colors to highlight prompt areas to vividly display this information to the user.

Lets start out with describing the Prompt Environment value:

Simply, PS1 and PS2 are prompt environment values that MAC OS X BASH uses (alot of this applies to other UNIX systems and the knowledge here can be transferred to Linux, HPUX, etc without very little change, if any) to customize how the terminal displays the prompt to the user.  PS1 & PS2 are primary and secondary prompts!    PS1's purpose as the primary prompt is to request commands from the user. The secondary prompt's purpose is to take further input from a command invoked from a PS1 prompt that request additional information.  An example of a PS1 prompt is listed below:



The prompt above represents the PS1 environment  variable.  Let's disect the prompt to understand how this was customized:
<Helios:sparc> 0 [02-12 08:57] ~ (0 Mb)
!




The first character is "<" in fact "<" & ">" are just that and are used as a visual representation of highlighting the information being conveyed.  This is also the purpose of these characters "[", "]", (" & ")", "!" and ":" through out the prompt.  

Helios is the HOST name of the computer

":" colon is a character to seperate the Host from the User ID (Personal Preference)

sparc is the user id.

The 0 is the number of jobs the user has running in the background.

The Date & Time is self explanatory.

is the current directory

O Mb is the total amount of bytes representing all the files in the current directory.

There is the format of this customized prompt, now
PS1="\n<\[\033[0;32m\]\h\[\033[0m\]:\[\033[0;37m\]\u\[\033[0m\]> \j [\$(date +%m-%d\" \"%H:%M)] \w (\[\033[0;36m\]\$(/Users/sparc/bin/TBytes.sh) Mb\[\033[0m\])\n! "
lets see the anatomy of this prompt and how the customization is achieved.






The above line is first put into .profile in the user directory.  This allows the prompt to persist from session to sesson.

\n is simply requesting a new line.

< just a character

\[ starts NON-PRINTING characters (Prepares to request color change)

\033[ escape sequence

0 uses default attribute [0 portion] for bold, underscore etc.

;32m sets the color

\] Ends the NON-PRINTING characters

The entire command is \[\033[0;32m\] Turns font color to blue

/h is the host

/u  user

(date +%m-%d\" \"%H:%M) Turns font color to white

\$ Expands to the process ID of the shell.  In a  ()  subshell,  in this case the date command is invoked to retrieve current Month/Day/Hour/Minute as seen below:

(date +%m-%d\" \"%H:%M)

\w   current working directory (pwd)

\$(/Users/sparc/bin/TBytes.sh) is another subshell request to a script file that reads the number of bytes used by the files in the current directory.  The script is below:

! cat ~/bin/TBytes.sh
#!/bin/bash
#Sum the number of bytes in a directory listing
TBytes=0
for Bytes in $(ls -l | grep "^-" | awk '{ print $5 }')
do
    let TBytes=$TBytes+$Bytes
done
TotalMeg=$(echo -e "scale=3 \n$TBytes/1048576 \nquit" | bc)
echo -n "$TotalMeg"





















\[\033[0m\] 
This sequence puts the font color back to the original prompt color

\n
New Line

!
Character to present for prompt user for input.

The following escape sequences and decodings are below:



\a

 an ASCII bell character (07)

\d

 thedatein "Weekday Month Date" format (e.g. Rue May 26)

\D{format}

 

 

the format is passed to strftime(3)andtheresultis

 

insertedinto 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

 thenameof 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 + patchelvel (e.g. 2.00.0)

\w

 the current working directory

\W

 the basename of the current working directory

\!

 the history number of this command

\#

 the command number of this command

\$

 if the effective UID is 0 a # otherwise $

\nnn

 the character corresponding to the octal number nnn

\\

 a backslash

\[

 begin a sequence of non-printing characters which could

 

 beusedtoembeda terminal control sequence into the

 

 prompt

\]

 end a sequence of non-printing characters

 

 PS1='[\u@TEST \w]\n \#\$ \n\

\[\

 end a sequence of non-printing characters




 

\e[1mBold Text\e[m\n\

 

\e[4mUnderline Text\e[m\n\

 

\e[5mBlink Text\e[m\n\

 

\e[7mInverse Text\e[m\]\n\

 

Should be normal text

 

Foreground colors:

 

\[\

\e[0;30m

 Black\n\

\e[0;31m

 Red\n\

\e[0;32m

 Green\n\

\e[0;33m

 Yellow\Orange\n\

\e[0;34m

 Blue\n\

\e[0;35m

 Magenta\n\

\e[0;36m

 Cyan\n\

\e[0;37m

 Light Gray\Black\n\

\e[0;39m

 Default\n\

Bright foreground colors:

 

\e[1;30m

 Dark Gray\n\

\e[1;31m

 Red\n\

\e[1;32m

 Green\n\

\e[1;33m

 Yellow\n\

\e[1;34m

 Blue\n\

\e[1;35m

 Magenta\n\

\e[1;36m

 Cyan\n\

\e[1;37m

 White\n\

\e[0;39m

 Default\n\

Background Colors

\e[m\]

\[\e[1;37m\e[40m:

 Black\e[0;49m\n\

\e[41m:

 Red\e[0;49m\n\

\e[42m:

 Green\e[0;49m\n\

\e[43m:

 Yellow\Orange\e[0;49m\n\

\e[44m:

 Blue\e[0;49m\n\

\e[45m:

 Magenta\e[0;49m\n\

\e[46m:

 Cyan\e[0;49m\n\

\e[47m:

 Light Gray\Black\e[0;49m\n\

\e[49m:

 Default\e[m\]\n'



There you go!

For more detail information from the terminal you can issue "man bash"

tags:        

links: digg this    del.icio.us    technorati    reddit




1. Klaus Wik left...
1 March 2007, Thursday 1:39 am

When you drag awk into it, why bother with grep and for? awk does it all:

TBytes = #ls -l | awk 'BEGIN {sum=0} /^-/ {sum+=$5} END {print sum}'#

Replace # with a grave accent. Apparently I am blogically challenged and can't find the grave.


2. SOS left...
1 March 2007, Thursday 9:20 am :: http://sos.blog-city.com/

Klaus,

This is a fabulous point! Well recommended and terse. I do like terse.

When I wrote this entry, my thoughts were more aligned with the capabilities of BASH Terminal Prompt Customization.

Thusly, showing the \$(/Users/sparc/bin/TBytes.sh) was to identify the capabilities of using a subshell request to a script file.

All in all, yes, your solution is cleaner.

Thank you,

Joseph


3. Fritz left...
27 June 2008, Friday 10:27 am

Awesome. Thanks for the tutorial.


4. SOS left...
2 July 2008, Wednesday 8:01 pm :: http://sos.blog-city.com/

Glad it helped!


5. Rafael Magaña left...
23 July 2010, Friday 10:10 am :: http://foo.raflabs.com

I made a kind of DSL in Ruby to generate valid strings that represent colored text in the terminal, I use it to generate my prompt: http://github.com/rafmagana/geek_painter


6. Rafael Magaña left...
23 July 2010, Friday 10:15 am :: http://foo.raflabs.com

I made a kind of DSL in Ruby to generate valid strings that represent colored text in the terminal, I use it to generate my prompt: http://github.com/rafmagana/geek_painter


7. SOS left...
8 June 2011, Wednesday 7:26 am :: http://blog.sensibleopensource.com/

Thank you!