  Bash Prompt HOWTO
  Giles Orr, giles@interlog.com
  v0.60, 07 January 1999

  Creating and controlling terminal and xterm prompts is discussed,
  including incorporating standard escape sequences to give username,
  current working directory, time, etc.  Further suggestions are made on
  how to modify xterm title bars, use external functions to provide
  prompt information, and how to use ANSI colours.
  ______________________________________________________________________

  Table of Contents






















































  1. Introduction and Administrivia

     1.1 Requirements
     1.2 How To Use This Document
     1.3 Translations
     1.4 Problems
     1.5 Send Me Comments and Suggestions
     1.6 Credits
     1.7 Copyright and Disclaimer

  2. Bash and Bash Prompts

     2.1 What is Bash?
     2.2 What can tweaking your Bash Prompt do for you?
     2.3 Why bother?
     2.4 The First Step
     2.5 Bash Prompt Escape Sequences
     2.6 Setting the PS? Strings Permanently

  3. External Commands

     3.1 PROMPT_COMMAND
     3.2 External Commands in the Prompt
     3.3 What to Put in Your Prompt
     3.4 Bash Environment and Functions

  4. Xterm Title Bar Manipulations

  5. ANSI Escape Sequences: Colours and Cursor Movement

     5.1 Colours
     5.2 Cursor Movement
     5.3 Moving the Cursor With tput

  6. Special Characters: Octal Escape Sequences

  7. The Bash Prompt Package

     7.1 Availability
     7.2 Changing the Xterm Font

  8. Loading a Different Prompt

     8.1 Loading a Different Prompt, Later
     8.2 Loading a Different Prompt, Immediately

  9. Loading Prompt Colours Dynamically

     9.1 A "Proof of Concept" Example

  10. Example Prompts

     10.1 A "Lightweight" Prompt
     10.2 Elite from Bashprompt Themes
     10.3 A "Power User" Prompt
     10.4 A Prompt the Width of Your Term
     10.5 The Elegant Useless Clock Prompt


  ______________________________________________________________________

  1.  Introduction and Administrivia




  1.1.  Requirements

  You will need Bash.  The default version on almost all Linux
  distributions is 1.14.7 (as of this writing, November 98), which is a
  well known and reliable shell.  Bash is now available in version 2.0+:
  I've been using Bash 2.0 for a while now, but almost all code
  presented here should work under 1.14.7.  If I'm aware of a problem,
  I'll mention it.  You can check your Bash version by typing echo
  $BASH_VERSION at the prompt.  On my machine, it responds with
  2.02.1(1)-release.


  Shell programming experience would be good, but isn't essential: the
  more you know, the more complex prompts you'll be able to create.  I
  assume a basic knowledge of shell programming and Unix utilities as I
  go through this tutorial.  However, my own shell programming skills
  are limited, so I give a lot of examples and explanation that may
  appear unnecessary to an experienced shell programmer.


  1.2.  How To Use This Document

  I include a lot of examples and explanatory text.  Different parts
  will be of varying usefulness to different people.  This has grown
  long enough that reading it straight through would be difficult - just
  read the sections you need, backtrack as necessary.


  1.3.  Translations

  As I write (6 January 99), translations are under weigh to both
  Japanese (Akira Endo, akendo@t3.rim.or.jp) and German (Thomas Keil,
  thomas@h-preissler.de).  Many thanks to both of them!  URLs will be
  included when they become available.


  1.4.  Problems

  This is a list of problems I've noticed while programming prompts.
  Don't start reading here, and don't let this list discourage you -
  these are mostly quite minor details.  Just check back if you run into
  anything odd.


  ·  Many Bash features (such as math within $(()) among others) are
     compile time options.  If you're using a binary distribution such
     as comes with an standard Linux distribution, all such features
     should be compiled in.  But if you're working on someone else's
     system, this is worth keeping in mind if something you expected to
     work doesn't.  Some notes about this in Learning the Bash Shell,
     p.260-262.

  ·  The terminal screen manager "screen" doesn't always get along with
     ANSI colours.  I'm not a screen expert, unfortunately.  My current
     version of screen (a very recent one) seems to work well in all
     cases, but I've seen occasions where screen reduced all prompt
     colours to the standard foreground colour in X terminals.  This
     doesn't appear to be a problem on the console.

  ·  Xdefaults files can override colours.  Look in  /.Xdefaults for
     lines referring to XTerm*background and XTerm*foreground (or
     possibly XTerm*Background and XTerm*Foreground).

  ·  One of the prompts mentioned in this document uses the output of
     "jobs" - as discussed at that time, "jobs" output to a pipe is
     broken in Bash 2.02.
  ·  ANSI cursor movement escape sequences aren't all implemented in all
     X terminals.  That's discussed in its own section.

  ·  Some nice looking pseudo-graphics can be created by using a VGA
     font rather than standard Linux fonts.  Unfortunately, these
     effects look awful if you don't use a VGA font, and there's no way
     to detect within a term what kind of font it's using.

  ·  Bash 2.0+ is out, and it incorporates some new features, and
     changes some behaviour.  Things that work under 1.14.7 don't
     necessarily work the same under 2.0+, or vice versa.


  1.5.  Send Me Comments and Suggestions

  This is a learning experience for me.  I've come to know a fair bit
  about what can be done to create interesting and useful Bash Prompts,
  but I need your input to correct and improve this document.  I've
  tried to check suggestions I make against different versions of Bash
  (mostly 2.02, which I use, and 1.14.7, which is in wide use), but let
  me know of any incompatibilities you find.


  The latest version of this document should always be available at
  http://www.interlog.com/~giles/bashprompt.html.  Please check this
  out, and feel free to e-mail me at giles@interlog.com with
  suggestions.


  I use the Linux Documentation Project HOWTOs almost exclusively in the
  HTML format, so when I convert this from SGML, HTML is the only format
  I check thoroughly.  If there are problems with other formats, I may
  not know about them, and I'd appreciate a note about them.


  1.6.  Credits

  In producing this document, I have borrowed heavily from the work of
  the Bashprompt project at http://bash.current.nu/.  Other sources used
  include the xterm Title mini-HOWTO by Ric Lister, available at
  http://sunsite.unc.edu/LDP/HOWTO/mini/Xterm-Title.html, Ansi Prompts
  by Keebler, available at http://www.ncal.verio.com/~keebler/ansi.html,
  How to make a Bash Prompt Theme by Stephen Webb, available at
  http://bash.current.nu/bash/HOWTO.html, and X ANSI Fonts by Stumpy,
  available at http://home.earthlink.net/~us5zahns/enl/ansifont.html.


  Also of immense help were several conversations and e-mails from Dan,
  a co-worker at Georgia College & State University, whose knowledge of
  Unix far exceeds mine.  He's given me several excellent suggestions,
  and ideas of his have led to some interesting prompts.


  Three books that have been very useful while programming prompts are
  Linux in a Nutshell by Jessica Heckman Perry (O'Reilly, 1997),
  Learning the Bash Shell by Cameron Newham and Bill Rosenblatt
  (O'Reilly, 2nd. ed., 1998) and Unix Shell Programming by Lowell Jay
  Arthur (Wiley, 1986.  This is the first edition, the fourth came out
  in 1997).


  1.7.  Copyright and Disclaimer

  This document is copyright 1998-1999 by Giles Orr.  You are encouraged
  to redistribute it.  You may not modify this document (see the section
  on contacting me: I have so far been incorporating all changes
  recommended by readers).  Please contact me if you're interested in
  doing a translation: that's one modification I can live with.


  This document is available for free, and, while I have done the best I
  can to make it accurate and up to date, I take no responsibility for
  any problems you may encounter resulting from the use of this
  document.


  2.  Bash and Bash Prompts

  2.1.  What is Bash?

  Descended from the Bourne Shell, Bash is a GNU product, the "Bourne
  Again SHell."  It's 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 don't know how much can be
  done.


  2.2.  What can tweaking your Bash Prompt do for you?

  Most Linux systems have a default prompt in one colour (usually gray)
  that tells you your user name, the name of the machine you're working
  on, and some indication of your current working directory.  This is
  all useful information, but you can do much more with the prompt: all
  sorts of information can be displayed (tty number, time, date, load,
  number of users, uptime ...) and the prompt can use ANSI colours,
  either to make it look interesting, or to make certain information
  stand out.  You can also manipulate the title bar of an Xterm to
  reflect some of this information.


  2.3.  Why bother?

  Beyond looking cool, it's often useful to keep track of system
  information.  One idea that I know appeals to some people is that it
  makes it possible to put prompts on different machines in different
  colours.  If you have several Xterms open on several different
  machines, or if you tend to forget what machine you're working on and
  delete the wrong files, you'll find this a great way to remember what
  machine you're on.


  2.4.  The First Step

  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 ways discussed here - since controlling
  it is exactly the same, and it isn't as "interesting," I'll mostly be
  modifying the PS1 string.  (There are also PS3 and PS4 strings.  These
  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 looks, you
  change the PS1 variable.  For experimentation purposes, you can enter
  the PS1 strings directly at the prompt, and see the results
  immediately (this only affects your current session, and the changes
  go away when you log out).  If you want to make a change to the prompt
  permanent, modify your  /.bashrc file, and add the new definition of
  PS1 there.  If you have root permissions, you can look in /etc/profile
  and modify the "PS1=" line.  Be aware that on some distributions
  (RedHat 5.1 at least) that the /etc/bashrc overrides the setting of
  the PS1 and PS2 strings.


  Before we get started, it's important to remember that the PS1 string
  is stored in the environment like any other environment variable.  If
  you modify it at the command line, your prompt will change.  Before
  you make any changes, you can save your current prompt to another
  environment variable:



       [giles@nikola giles]$ SAVE=$PS1
       [giles@nikola giles]$





  The simplest prompt would be a single character, such as:



       [giles@nikola giles]$ PS1=$
       $ls
       bin   mail
       $





  This demonstrates the best way to experiment with basic prompts,
  entering them at the command line.  Notice that the text entered by
  the user appears immediately after the prompt: I prefer to use



       $PS1="$ "
       $ ls
       bin   mail
       $





  which forces a space after the prompt, making it more readable.  To
  restore your original prompt, just call up the variable you stored:



       $ PS1=$SAVE
       [giles@nikola giles]$





  2.5.  Bash Prompt Escape Sequences

  There are a lot of escape sequences offered by the Bash shell for
  insertion in the prompt.  From the Bash 2.02 man page:







  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
         \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





  Continuing where we left off:



       [giles@nikola giles]$ PS1="\u@\h \W> "
       giles@nikola giles> ls
       bin   mail
       giles@nikola giles>





  This is similar to the default on most Linux distributions.  I wanted
  a slightly different appearance, so I changed this to:



       giles@nikola giles> PS1="[\t][\u@\h:\w]\$ "
       [21:52:01][giles@nikola:~]$ ls
       bin   mail
       [21:52:15][giles@nikola:~]$


  2.6.  Setting the PS? Strings Permanently

  Various people and distributions set their PS? strings in different
  places.  The most common places are /etc/profile, /etc/bashrc,
   /.bash_profile, and  /.bashrc .  Johan Kullstam (johan19@idt.net)
  writes:



       the PS1 string should be set in .bashrc.  this is because
       non-interactive bashes go out of their way to unset PS1.  the bash man
       page tells how the presence or absence of PS1 is a good way of knowing
       whether one is in an interactive vs non-interactive (ie script) bash
       session.

       the way i realized this is that startx is a bash script.  what this
       means is, startx will wipe out your prompt.  when you set PS1 in
       .profile (or .bash_profile), login at console, fire up X via startx,
       your PS1 gets nuked in the process leaving you with the default
       prompt.

       one workaround is to launch xterms and rxvts with the -ls option to
       force them to read .profile.  but any time a shell is called via a
       non-interactive shell-script middleman PS1 is lost.  system(3) uses sh
       -c which if sh is bash will kill PS1.  a better way is to place the
       PS1 definition in .bashrc.  this is read every time bash starts and is
       where interactive things - eg PS1 should go.

       therefore it should be stressed that PS1=..blah.. should be in .bashrc
       and not .profile.





  I tried to duplicate the problem he explains, and encountered a
  different one: my PROMPT_COMMAND variable (which will be introduced
  later) was blown away.  My knowledge in this area is somewhat shaky,
  so I'm going to go with what Johan says.


  3.  External Commands

  3.1.  PROMPT_COMMAND

  Bash provides another 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]\$ "
       [giles@nikola:~] PROMPT_COMMAND="date +%H%M"
       2155
       [giles@nikola:~] d
       bin   mail
       2156
       [giles@nikola:~]





  What happened above was that I changed PS1 to no longer include the \t
  escape sequence, so the 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.  But
  it appears on a different line than the prompt.  Tidying this up using
  echo -n ... as shown below works with Bash 2.0+, but appears not to
  work with Bash 1.14.7: apparently the prompt is drawn in a different
  way, and the following method results in overlapping text.



       2156
       [giles@nikola:~] PROMPT_COMMAND="echo -n [$(date +%H%M)]"
       [2156][giles@nikola:~]$
       [2156][giles@nikola:~]$ d
       bin   mail
       [2157][giles@nikola:~]$ unset PROMPT_COMMAND
       [giles@nikola:~]





  echo -n ... controls the output of the date command and supress the
  trailing newline, allowing the prompt to appear all on one line.  At
  the end, I used the unset command to remove the PROMPT_COMMAND
  environment variable.


  Note that I 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 2.0+.  In some older versions of Bash, prior to 1.14.7,
  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.  I will continue to use this convention throughout this
  document.  If you're using an earlier version of Bash, you can usually
  substitute backquotes where you see $().  If the command substitution
  is escaped (ie. \$(command) ), then use backslashes to escape BOTH
  your backquotes (ie. \'command\' ).


  3.2.  External Commands in the Prompt

  You can use the output of regular Linux commands directly in the
  prompt as well.  Obviously, you don't want to insert a lot of
  material, or it will create a large prompt.  You also want to use a
  fast command, because it's going to be executed every time your prompt
  appears on the screen, and delays in the appearance of your prompt
  while you're working can be very annoying.  (Unlike the previous
  example that this closely resembles, this does work with Bash 1.14.7.)



       [21:58:33][giles@nikola:~]$ PS1="[\$(date +%H%M)][\u@\h:\w]\$ "
       [2159][giles@nikola:~]$ ls
       bin   mail
       [2200][giles@nikola:~]$



  It's important to notice 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, that would mean that it would display the same time no
  matter how long the prompt was used.  The backslash protects the
  contents of $() from immediate shell interpretation, so "date" is
  called every time a prompt is generated.


  Linux comes with a lot of small utility programs like date, grep, or
  wc that allow you to manipulate data.  If you find yourself trying to
  create complex combinations of these programs within a prompt, it may
  be easier to make a shell script of your own, and call it from the
  prompt.  Escape sequences are often required in bash shell scripts to
  ensure that shell variables are expanded at the correct time (as seen
  above with the date command): this is raised to another level within
  the prompt PS1 line, and avoiding it by creating shell scripts is a
  good idea.


  An example of a small shell script used within a prompt is given
  below:


  ______________________________________________________________________
  #!/bin/bash
  #     lsbytesum - sum the number of bytes in a directory listing
  TotalBytes=0
  for Bytes in $(ls -l | grep "^-" | cut -c30-41)
  do
      let TotalBytes=$TotalBytes+$Bytes
  done
  TotalMeg=$(echo -e "scale=3 \n$TotalBytes/1048576 \nquit" | bc)
  echo -n "$TotalMeg"
  ______________________________________________________________________





  I have at times kept this both as a function (much more efficient -
  unfortunately, explaining functions in detail is beyond the scope of
  this document), or as a shell script in my  /bin directory, which is
  on my path.  Used in a prompt:



       [2158][giles@nikola:~]$ PS1="[\u@\h:\w (\$(lsbytesum) Mb)]\$ "
       [giles@nikola:~ (0 Mb)]$ cd /bin
       [giles@nikola:/bin (4.498 Mb)]$





  3.3.  What to Put in Your Prompt

  You'll find I put username, machine name, time, and current directory
  name in most of my prompts.  With the exception of the time, these are
  very standard items to find in a prompt, and time is probably the next
  most common addition.  But what you include is entirely a matter of
  personal taste.  Here are examples from people I know to help give you
  ideas.



  Dan's prompt is minimal but very effective, particularly for the way
  he works.



       [giles@nikola:~]$ cur_tty=$(tty | sed -e "s/.*tty\(.*\)/\1/")
       [giles@nikola:~]$ echo $cur_tty
       p4
       [giles@nikola:~]$ PS1="\!,$cur_tty,\$?\$ "
       1095,p4,0$





  Dan doesn't like that having the current working directory can resize
  the prompt drastically as you move through the directory tree, so he
  keeps track of that in his head (or types "pwd").  He learned Unix
  with csh and tcsh, so he uses his command history extensively
  (something many of us weened on Bash do not do), so the first item in
  the prompt is the history number.  The second item is the significant
  characters of the tty (the output of "tty" is cropped with sed), an
  item that can be useful to "screen" users.  The third item is the exit
  value of the last command/pipeline (note that this is rendered useless
  by any command executed within the prompt - you could work around that
  by capturing it to a variable and playing it back, though).  Finally,
  the "\$" is a dollar sign for a regular user, and switches to a hash
  mark ("#") if the user is root.


  Torben Fjerdingstad wrote to tell me that he often suspends jobs, and
  then forgets about them, so he uses his prompt to remind him of
  suspended jobs:



       [giles@nikola:~]$ function jobcount {
       > jobs|wc -l| awk '{print $1}'
       > }
       [giles@nikola:~]$ export PS1='\W[`jobcount`]# '
       giles[0]# man ls &
       [1] 4150

       [1]+  Stopped (tty output)    man ls
       giles[1]#





  Torben uses awk to trim the whitespace from the output of wc, while I
  would have used sed or tr - not because they're better, but because
  I'm more familiar with them.  There are probably other ways as well.
  Torben also surrounds his PS1 string in single quotes, which prevent
  Bash from immediately interpreting the backquotes, so he doesn't have
  to escape them as I have mentioned.


  NOTE: There is a known bug in Bash 2.02 that causes the jobs command
  (a shell builtin) to return nothing to a pipe.  If you try the above
  under Bash 2.02, you will always get a "0" back regardless of how many
  jobs you have suspended.  Chet Ramey, one of the maintainers of Bash,
  tells me that this will be fixed for v2.03.



  3.4.  Bash Environment and Functions

  As mentioned earlier, PS1, PS2, PS3, PS4, and PROMPT_COMMAND are all
  stored in the Bash environment.  For those of us coming from a DOS
  background, the idea of tossing big hunks of code into the environment
  is horrifying, because that DOS environment was small, and didn't
  exactly grow well.  There are probably practical limits on what you
  can and should put in the environment, but I don't know what they are,
  and we're probably talking a couple of orders of magnitude larger than
  what DOS users are used to.  As Dan put it:


  "In my interactive shell I have 62 aliases and 25 functions.  My rule
  of thumb is that if I need something solely for interactive use and
  can handily write it in bash I make it a shell function (assuming it
  can't be easily expressed as an alias).  If these people are worried
  about memory they don't need to be using bash.  Bash is one of the
  largest programs I run on my linux box (outside of Oracle).  Run top
  sometime and press 'M' to sort by memory - see how close bash is to
  the top of the list.  Heck, it's bigger than sendmail!  Tell 'em to go
  get ash or something."


  I guess he was using console only the day he tried that: running X and
  X apps, I have a lot of stuff larger than Bash.  But the idea is the
  same: the environment is something to be used, and don't worry about
  overfilling it.


  I risk censure by Unix gurus when I say this (for the crime of over-
  simplification), but functions are basically small shell scripts that
  are loaded into the environment for the purpose of efficiency.
  Quoting Dan again: "Shell functions are about as efficient as they can
  be.  It is the approximate equivalent of sourcing a bash/bourne shell
  script save that no file I/O need be done as the function is already
  in memory.  The shell functions are typically loaded from [.bashrc or
  .bash_profile] depending on whether you want them only in the initial
  shell or in subshells as well.  Contrast this with running a shell
  script: Your shell forks, the child does an exec, potentially the path
  is searched, the kernel opens the file and examines enough bytes to
  determine how to run the file, in the case of a shell script a shell
  must be started with the name of the script as its argument, the shell
  then opens the file, reads it and executes the statements.  Compared
  to a shell function, everything other than executing the statments can
  be considered unnecessary overhead."


  4.  Xterm Title Bar Manipulations

  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.


  If you try to change the title bar of your Xterm with your prompt when
  you're at the console, you'll produce garbage in your prompt.  To
  avoid this, test the TERM environment variable to tell if your prompt
  is going to be in an Xterm.



  ______________________________________________________________________
  function proml
  {
  case $TERM in
      xterm*)
          local TITLEBAR='\[\033]0;\u@\h:\w\007\]'
          ;;
      *)
          local TITLEBAR=''
          ;;
  esac

  PS1="${TITLEBAR}\
  [\$(date +%H%M)]\
  [\u@\h:\w]\
  \$ "
  PS2='> '
  PS4='+ '
  }
  ______________________________________________________________________




  This is a function that can be incorporated into  /.bashrc.  The
  function name could 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 with unset proml.  Since the prompt can't change from
  being in an Xterm to being at the console, the TERM variable isn't
  tested every 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 Bashprompt package
  (discussed later in this document) deals with prompts: it's 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 make them into some sort of text
  file.  In this case, to test this at the prompt, save the above as a
  text file called "proml".  You can work with it as follows:



       [giles@nikola:/bin (4.498 Mb)]$ cd          -> Go where you want to save the prompt
       [giles@nikola:~ (0 Mb)]$ vi proml           -> Edit the prompt file
       ...                                         -> Enter the text given above
       [giles@nikola:~ (0 Mb)]$ source proml       -> Read the prompt function
       [giles@nikola:~ (0 Mb)]$ proml              -> Execute the prompt function





  The first step in creating this prompt is to test if the shell we're
  starting is an xterm or not: if it is, 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 particularily useful with
  minimized Xterms, making them more rapidly identifiable.  The other
  material in this prompt should be familiar from previous prompts we've
  created.


  The only drawback to manipulating the Xterm title bar like this occurs
  when you log into a system on which you haven't set up the title bar
  hack: the Xterm will continue to show the information from the
  previous system that had the title bar hack in place.


  5.  ANSI Escape Sequences: Colours and Cursor Movement

  5.1.  Colours

  As mentioned before, non-printing escape sequences have to be enclosed
  in \[\033[ and \].  For colour escape sequences, they should also be
  followed by a lowercase m.


  If you try out the following prompts in an xterm and find that you
  aren't seeing the colours named, check out your  /.Xdefaults file (and
  possibly its bretheren) for lines like "XTerm*Foreground:
  BlanchedAlmond".  This can be commented out by placing an exclamation
  mark ("!") in front of it.  Of course, this will also be dependent on
  what terminal emulator you're using.  This is the likeliest place that
  your term foreground colours would be overridden.


  To include blue text in the prompt:



       PS1="\[\033[34m\][\$(date +%H%M)][\u@\h:\w]$ "




  The problem with this prompt is that the blue colour that starts with
  the 34 colour code is never switched back to the regular colour, so
  any text you type after the prompt is still in the colour of the
  prompt.  This is also a dark shade of blue, so combining it with the
  bold code might help:



       PS1="\[\033[1;34m\][\$(date +%H%M)][\u@\h:\w]$\[\033[0m\] "





  The prompt is now in light blue, and it ends by switching the colour
  back to nothing (whatever foreground colour you had previously).


  Here are the rest of the colour equivalences:



       Black       0;30     Dark Gray     1;30
       Blue        0;34     Light Blue    1;34
       Green       0;32     Light Green   1;32
       Cyan        0;36     Light Cyan    1;36
       Red         0;31     Light Red     1;31
       Purple      0;35     Light Purple  1;35
       Brown       0;33     Yellow        1;33
       Light Gray  0;37     White         1;37



  You can also set background colours by using 44 for Blue background,
  41 for a Red background, etc.  There are no bold background colours.
  Combinations can be used, like Light Red text on a Blue background:
  \[\033[44;1;31m\], although setting the colours separately seems to
  work better (ie. \[\033[44m\]\[\033[1;31m\]).  Other codes available
  include 4: Underscore, 5: Blink, 7: Inverse, and 8: Concealed.


  Aside: Many people (myself included) object strongly to the "blink"
  attribute.  Fortunately, it doesn't work in any terminal emulators
  that I'm aware of - but it will still work on the console.  And, if
  you were wondering (as I did) "What use is a 'Concealed' attribute?!"
  - I saw it used in an example shell script (not a prompt) to allow
  someone to type in a password without it being echoed to the screen.


  Based on a prompt called "elite2" in the Bashprompt package (which I
  have modified to work better on a standard console, rather than with
  the special xterm fonts required to view the original properly), this
  is a prompt I've used a lot:


  ______________________________________________________________________

  function elite
  {

  local GRAY="\[\033[1;30m\]"
  local LIGHT_GRAY="\[\033[0;37m\]"
  local CYAN="\[\033[0;36m\]"
  local LIGHT_CYAN="\[\033[1;36m\]"

  case $TERM in
      xterm*)
          local TITLEBAR='\[\033]0;\u@\h:\w\007\]'
          ;;
      *)
          local TITLEBAR=""
          ;;
  esac

  local GRAD1=$(tty|cut -d/ -f3)
  PS1="$TITLEBAR\
  $GRAY-$CYAN-$LIGHT_CYAN(\
  $CYAN\u$GRAY@$CYAN\h\
  $LIGHT_CYAN)$CYAN-$LIGHT_CYAN(\
  $CYAN\#$GRAY/$CYAN$GRAD1\
  $LIGHT_CYAN)$CYAN-$LIGHT_CYAN(\
  $CYAN\$(date +%H%M)$GRAY/$CYAN\$(date +%d-%b-%y)\
  $LIGHT_CYAN)$CYAN-$GRAY-\
  $LIGHT_GRAY\n\
  $GRAY-$CYAN-$LIGHT_CYAN(\
  $CYAN\$$GRAY:$CYAN\w\
  $LIGHT_CYAN)$CYAN-$GRAY-$LIGHT_GRAY "
  PS2="$LIGHT_CYAN-$CYAN-$GRAY-$LIGHT_GRAY "
  }
  ______________________________________________________________________




  I define the colours as temporary shell variables in the name of
  readability.  It's easier to work with.  The "GRAD1" variable is a
  check to determine what terminal you're on.  Like the test to
  determine if you're working in an Xterm, it only needs to be done
  once.  The prompt you see look like this, except in colour:
       --(giles@nikola)-(75/ttyp7)-(1908/12-Oct-98)--
       --($:~/tmp)--





  To help myself remember what colours are available, I wrote the
  following script which echoes all the colours to screen:

























































  ______________________________________________________________________
  #!/bin/bash
  #
  #   This file echoes a bunch of colour codes to the terminal to demonstrate
  #   what's available.  Each line is one colour on black and gray
  #   backgrounds, with the code in the middle.  Verified to work on white,
  #   black, and green BGs (2 Dec 98).
  #
  echo "  On Light Gray:        On Black:"
  echo -e "\033[47m\033[1;37m  White        \033[0m\
   1;37m \
  \033[40m\033[1;37m  White        \033[0m"
  echo -e "\033[47m\033[37m  Light Gray   \033[0m\
     37m \
  \033[40m\033[37m  Light Gray   \033[0m"
  echo -e "\033[47m\033[1;30m  Gray         \033[0m\
   1;30m \
  \033[40m\033[1;30m  Gray         \033[0m"
  echo -e "\033[47m\033[30m  Black        \033[0m\
     30m \
  \033[40m\033[30m  Black        \033[0m"
  echo -e "\033[47m\033[31m  Red          \033[0m\
     31m \
  \033[40m\033[31m  Red          \033[0m"
  echo -e "\033[47m\033[1;31m  Light Red    \033[0m\
   1;31m \
  \033[40m\033[1;31m  Light Red    \033[0m"
  echo -e "\033[47m\033[32m  Green        \033[0m\
     32m \
  \033[40m\033[32m  Green        \033[0m"
  echo -e "\033[47m\033[1;32m  Light Green  \033[0m\
   1;32m \
  \033[40m\033[1;32m  Light Green  \033[0m"
  echo -e "\033[47m\033[33m  Brown        \033[0m\
     33m \
  \033[40m\033[33m  Brown        \033[0m"
  echo -e "\033[47m\033[1;33m  Yellow       \033[0m\
   1;33m \
  \033[40m\033[1;33m  Yellow       \033[0m"
  echo -e "\033[47m\033[34m  Blue         \033[0m\
     34m \
  \033[40m\033[34m  Blue         \033[0m"
  echo -e "\033[47m\033[1;34m  Light Blue   \033[0m\
   1;34m \
  \033[40m\033[1;34m  Light Blue   \033[0m"
  echo -e "\033[47m\033[35m  Purple       \033[0m\
     35m \
  \033[40m\033[35m  Purple       \033[0m"
  echo -e "\033[47m\033[1;35m  Pink         \033[0m\
   1;35m \
  \033[40m\033[1;35m  Pink         \033[0m"
  echo -e "\033[47m\033[36m  Cyan         \033[0m\
     36m \
  \033[40m\033[36m  Cyan         \033[0m"
  echo -e "\033[47m\033[1;36m  Light Cyan   \033[0m\
   1;36m \
  \033[40m\033[1;36m  Light Cyan   \033[0m"
  ______________________________________________________________________




  5.2.  Cursor Movement

  ANSI escape sequences allow you to move the cursor around the screen
  at will.  This is more useful for full screen user interfaces
  generated by shell scripts, but can also be used in prompts.  The
  movement escape sequences are as follows:



       - Position the Cursor:
         \033[<L>;<C>H
         puts the cursor at line L and column C.
       - Move the cursor up N lines:
         \033[<N>A
       - Move the cursor down N lines:
         \033[<N>B
       - Move the cursor forward N columns:
         \033[<N>C
       - Move the cursor backward N columns:
         \033[<N>D

       - Save cursor position:
         \033[s
       - Restore cursor position:
         \033[u





  The latter two codes are NOT honoured by many terminal emulators.  The
  only ones that I'm aware of that do are xterm and nxterm - even though
  the majority of terminal emulators are based on xterm code.  As far as
  I can tell, rxvt, kvt, xiterm, and Eterm do not support this.  They
  are supported on the console.


  Try putting in the following line of code at the prompt (it's a little
  clearer what it does if the prompt is several lines down the terminal
  when you put this in): echo -en "\033[7A\033[1;35m BASH
  \033[7B\033[6D" This should move the cursor seven lines up screen,
  print the word " BASH ", and then return to where it started to
  produce a normal prompt.  This isn't a prompt: it's just a
  demonstration of moving the cursor on screen, using colour to
  emphasize what has been done.


  Save this in a file called "clock":






















  ______________________________________________________________________
  #!/bin/bash

  function prompt_command {
  let prompt_x=$COLUMNS-5
  }

  PROMPT_COMMAND=prompt_command

  function clock {
  local       BLUE="\[\033[0;34m\]"
  local        RED="\[\033[0;31m\]"
  local  LIGHT_RED="\[\033[1;31m\]"
  local      WHITE="\[\033[1;37m\]"
  local  NO_COLOUR="\[\033[0m\]"
  case $TERM in
      xterm*)
          TITLEBAR='\[\033]0;\u@\h:\w\007\]'
          ;;
      *)
          TITLEBAR=""
          ;;
  esac

  PS1="${TITLEBAR}\
  \[\033[s\033[1;\$(echo -n \${prompt_x})H\]\
  $BLUE[$LIGHT_RED\$(date +%H%M)$BLUE]\[\033[u\033[1A\]
  $BLUE[$LIGHT_RED\u@\h:\w$BLUE]\
  $WHITE\$$NO_COLOUR "
  PS2='> '
  PS4='+ '
  }
  ______________________________________________________________________




  This prompt is fairly plain, except that it keeps a 24 hour clock in
  the upper right corner of the terminal (even if the terminal is
  resized).  This will NOT work on the terminal emulators that I
  mentioned that don't accept the save and restore cursor position
  codes.  If you try to run this prompt in any of those terminal
  emulators, the clock will appear correctly, but the prompt will be
  trapped on the second line of the terminal.


  See also ``The Elegant Useless Clock Prompt'' for a more extensive use
  of these codes.


  5.3.  Moving the Cursor With tput

  As with so many things in Unix, there is more than one way to achieve
  the same ends.  A utility called "tput" can also be used to move the
  cursor around the screen, or get back information about the status of
  the terminal.  "tput" for cursor positioning is less flexible than
  ANSI escape sequences: you can only move the cursor to an absolute
  position, you can't move it relative to its current position.  I don't
  use "tput," so I'm not going to explain it in detail.  Type "man tput"
  and you'll know as much as I do.


  6.  Special Characters: Octal Escape Sequences

  Outside of the characters that you can type on your keyboard, there
  are a lot of other characters you can print on your screen.  I've
  created a script to allow you to check out what the font you're using
  has available for you.  The main command you need to use to utilise
  these characters is "echo -e".  The "-e" switch tells echo to enable
  interpretation of backslash-escaped characters.  What you see when you
  look at octal 200-400 will be very different with a VGA font from what
  you will see with a standard Linux font.  Be warned that some of these
  escape sequences have odd effects on your terminal, and I haven't
  tried to prevent them from doing whatever they do.  The linedraw and
  block characters (which many of us became familiar with with Word
  Perfect) that are used heavily by the Bashprompt project are between
  octal 260 and 337.























































  ______________________________________________________________________
  #!/bin/bash

  #   Script: escgen

  function usage {
     echo -e "\033[1;34mescgen\033[0m <lower_octal_value> [<higher_octal_value>]"
     echo "   Octal escape sequence generator: print all octal escape sequences"
     echo "   between the lower value and the upper value.  If a second value"
     echo "   isn't supplied, print eight characters."
     echo "   1998 - Giles Orr, no warranty."
     exit 1
  }

  if [ "$#" -eq "0" ]
  then
     echo -e "\033[1;31mPlease supply one or two values.\033[0m"
     usage
  fi
  let lower_val=${1}
  if [ "$#" -eq "1" ]
  then
     #   If they don't supply a closing value, give them eight characters.
     upper_val=$(echo -e "obase=8 \n ibase=8 \n $lower_val+10 \n quit" | bc)
  else
     let upper_val=${2}
  fi
  if [ "$#" -gt "2" ]
  then
     echo -e "\033[1;31mPlease supply two values.\033[0m"
     echo
     usage
  fi
  if [ "${lower_val}" -gt "${upper_val}" ]
  then
     echo -e "\033[1;31m${lower_val} is larger than ${upper_val}."
     echo
     usage
  fi
  if [ "${upper_val}" -gt "777" ]
     then
     echo -e "\033[1;31mValues cannot exceed 777.\033[0m"
     echo
     usage
  fi

  let i=$lower_val
  let line_count=1
  let limit=$upper_val
  while [ "$i" -lt "$limit" ]
  do
     octal_escape="\\$i"
     echo -en "$i:'$octal_escape' "
     if [ "$line_count" -gt "7" ]
     then
        echo
        #   Put a hard return in.
        let line_count=0
     fi
     let i=$(echo -e "obase=8 \n ibase=8 \n $i+1 \n quit" | bc)
     let line_count=$line_count+1
  done
  echo
  ______________________________________________________________________


  You can also use xfd to display all the characters in an X font, with
  the command "xfd -fn <fontname>".  Clicking on any given character
  will give you lots of information about that character, including its
  octal value.  The script given above will be useful on the console,
  and if you aren't sure of the current font name.


  7.  The Bash Prompt Package

  7.1.  Availability

  The Bash Prompt package is available at http://bash.current.nu, and is
  the work of several people, co-ordinated by Rob Current (aka
  BadLandZ).  The package is an early beta, but offers a simple way of
  using multiple prompts (or themes), allowing you to set prompts for
  login shells, and for subshells (ie. putting PS1 strings in
   /.bash_profile and  /.bashrc).  Most of the themes use the extended
  VGA character set, so they look bad unless they're used with VGA fonts
  (which aren't the default on most systems).


  7.2.  Changing the Xterm Font

  To use some of the most attractive prompts in the Bash Prompt package,
  you need to get and install fonts that support the character sets
  expected by the prompts.  These are referred to as "VGA Fonts," but
  I'm unclear on the distinction between them and the fonts Linux
  usually ships with - although clearly they support different character
  sets.  Standard Xterm fonts support an extended alphabet, including a
  lot of letters with accents.  In VGA fonts, this material is replaced
  by graphical characters - blocks, dots, lines.  If anyone can explain
  this in more detail, e-mail me and I'll include the explanation here.


  Getting and installing these fonts is a somewhat involved process.
  First, retrieve the font(s).  Next, ensure they're .pcf or .pcf.gz
  files.  If they're .bdf files, investigate the "bdftopcf" command (ie.
  read the man page).  Drop the .pcf or .pcf.gz files into the
  /usr/X11R6/lib/X11/fonts/misc dir (this is the correct directory for
  RedHat 5.1 and Slackware 3.4, it may be different on other
  distributions).  "cd" to that directory, and run the "mkfontdir"
  command.  Then run "xset fp rehash".  Sometimes it's a good idea to go
  into the fonts.alias file in the same directory, and create shorter
  alias names for the fonts.


  To use the new fonts, you start your Xterm program of choice with the
  appropriate command to your Xterm, which can be found either in the
  man page or by using the "--help" parameter on the command line.
  Popular terms would be used as follows:



       xterm -font <fontname>




  OR


       xterm -fn <fontname> -fb <fontname-bold>
       Eterm -f <fontname>
       rxvt -fn <fontname>


  VGA fonts are available from Stumpy's ANSI Fonts page at
  http://home.earthlink.net/~us5zahns/enl/ansifont.html (which I have
  borrowed from extensively while writing this).


  8.  Loading a Different Prompt

  8.1.  Loading a Different Prompt, Later

  The explanations in this HOWTO have shown how to make PS1 environment
  variables, or how to incorporate those PS1 and PS2 strings into
  functions that could be called by  /.bashrc or as a theme by the
  bashprompt package.


  Using the bashprompt package, you would type bashprompt -i to see a
  list of available themes.  To set the prompt in future login shells
  (primarily the console, but also telnet and Xterms, depending on how
  your Xterms are set up), you would type bashprompt -l themename.
  bashprompt then modifies your  /.bash_profile to call the requested
  theme when it starts.  To set the prompt in future subshells (usually
  Xterms, rxvt, etc.), you type bashprompt -s themename, and bashprompt
  modifies your  /.bashrc file to call the appropriate theme at startup.


  See also ``Setting the PS? Strings Permanently'' for Johan Kullstam's
  note regarding the importance of putting the PS?  strings in  /.bashrc
  .


  8.2.  Loading a Different Prompt, Immediately

  You can change the prompt in your current terminal (using the example
  "elite" function above) by typing "source elite" followed by "elite"
  (assuming that the elite function file is the working directory).
  This is somewhat cumbersome, and leaves you with an extra function
  (elite) in your environment space - if you want to clean up the
  environment, you would have to type "unset elite" as well.  This would
  seem like an ideal candidate for a small shell script, but a script
  doesn't work here because the script cannot change the environment of
  your current shell: it can only change the environment of the subshell
  it runs in.  As soon as the script stops, the subshell goes away, and
  the changes the script made to the environment are gone.  What can
  change environment variables of your current shell are environment
  functions.  The bashprompt package puts a function called
  "callbashprompt" into your environment, and, while they don't document
  it, it can be called to load any bashprompt theme on the fly.  It
  looks in the theme directory it installed (the theme you're calling
  has to be there), sources the function you asked for, loads the
  function, and then unsets the function, thus keeping your environment
  uncluttered.  "callbashprompt" wasn't intended to be used this way,
  and has no error checking, but if you keep that in mind, it works
  quite well.


  9.  Loading Prompt Colours Dynamically

  9.1.  A "Proof of Concept" Example

  This is a "proof of concept" more than an attractive prompt: changing
  colours within the prompt dynamically.  In this example, the colour of
  the host name changes depending on the load (as a warning).




  ______________________________________________________________________
  #!/bin/bash
  #   "hostloadcolour" - 17 October 98, by Giles
  #
  #   The idea here is to change the colour of the host name in the prompt,
  #   depending on a threshold load value.

  # THRESHOLD_LOAD is the value of the one minute load (multiplied
  # by one hundred) at which you want
  # the prompt to change from COLOUR_LOW to COLOUR_HIGH
  THRESHOLD_LOAD=200
  COLOUR_LOW='1;34'
            # light blue
  COLOUR_HIGH='1;31'
             # light red

  function prompt_command {
  ONE=$(uptime | sed -e "s/.*load average: \(.*\...\), \(.*\...\), \(.*\...\)/\1/" -e "s/ //g")
  #   Apparently, "scale" in bc doesn't apply to multiplication, but does
  #   apply to division.
  ONEHUNDRED=$(echo -e "scale=0 \n $ONE/0.01 \nquit \n" | bc)
  if [ $ONEHUNDRED -gt $THRESHOLD_LOAD ]
  then
      HOST_COLOUR=$COLOUR_HIGH
          # Light Red
  else
      HOST_COLOUR=$COLOUR_LOW
          # Light Blue
  fi
  }

  function hostloadcolour {

  PROMPT_COMMAND=prompt_command
  PS1="[$(date +%H%M)][\u@\[\033[\$(echo -n \$HOST_COLOUR)m\]\h\[\033[0;37m\]:\w]$ "
  }
  ______________________________________________________________________




  Using your favorite editor, save this to a file named
  "hostloadcolour".  If you have the Bashprompt package installed, this
  will work as a theme.  If you don't, type source hostloadcolour and
  then hostloadcolour.  Either way, "prompt_command" becomes a function
  in your environment.  If you examine the code, you will notice that
  the colours ($COLOUR_HIGH and $COLOUR_LOW) are set using only a
  partial colour code, ie. "1;34" instead of "\[\033[1;34m\]", which I
  would have preferred.  I have been unable to get it to work with the
  complete code.  Please let me know if you manage this.



  10.  Example Prompts

  10.1.  A "Lightweight" Prompt










  ______________________________________________________________________

  function proml {
  local BLUE="\[\033[0;34m\]"
  local RED="\[\033[0;31m\]"
  local LIGHT_RED="\[\033[1;31m\]"
  local WHITE="\[\033[1;37m\]"
  local NO_COLOUR="\[\033[0m\]"
  case $TERM in
      xterm*)
          TITLEBAR='\[\033]0;\u@\h:\w\007\]'
          ;;
      *)
          TITLEBAR=""
          ;;
  esac

  PS1="${TITLEBAR}\
  $BLUE[$RED\$(date +%H%M)$BLUE]\
  $BLUE[$LIGHT_RED\u@\h:\w$BLUE]\
  $WHITE\$$NO_COLOUR "
  PS2='> '
  PS4='+ '
  }
  ______________________________________________________________________




  10.2.  Elite from Bashprompt Themes

  Note that this requires a VGA font.


  ______________________________________________________________________

  # Created by KrON from windowmaker on IRC
  # Changed by Spidey 08/06
  function elite {
  PS1="\[\033[31m\]\332\304\[\033[34m\](\[\033[31m\]\u\[\033[34m\]@\[\033[31m\]\h\
  \[\033[34m\])\[\033[31m\]-\[\033[34m\](\[\033[31m\]\$(date +%I:%M%P)\
  \[\033[34m\]-:-\[\033[31m\]\$(date +%m)\[\033[34m\033[31m\]/\$(date +%d)\
  \[\033[34m\])\[\033[31m\]\304-\[\033[34m]\\371\[\033[31m\]-\371\371\
  \[\033[34m\]\372\n\[\033[31m\]\300\304\[\033[34m\](\[\033[31m\]\W\[\033[34m\])\
  \[\033[31m\]\304\371\[\033[34m\]\372\[\033[00m\]"
  PS2="> "
  }
  ______________________________________________________________________




  10.3.  A "Power User" Prompt

  I actually do use this prompt, but it results in noticeable delays in
  the appearance of the prompt on a single-user PII-400, so I wouldn't
  recommend using it on a multi-user P-100 or anything ...  Look at it
  for ideas, rather than as a practical prompt.








  ______________________________________________________________________

  #!/bin/bash
  #----------------------------------------------------------------------
  #       POWER USER PROMPT "pprom2"
  #----------------------------------------------------------------------
  #
  #   Created August 98, Last Modified 9 November 98 by Giles
  #
  #   Problem: when load is going down, it says "1.35down-.08", get rid
  #   of the negative

  function prompt_command
  {
  #   Create TotalMeg variable: sum of visible file sizes in current directory
  local TotalBytes=0
  for Bytes in $(ls -l | grep "^-" | cut -c30-41)
  do
      let TotalBytes=$TotalBytes+$Bytes
  done
  TotalMeg=$(echo -e "scale=3 \nx=$TotalBytes/1048576\n if (x<1) {print \"0\"} \n print x \nquit" | bc)

  #      This is used to calculate the differential in load values
  #      provided by the "uptime" command.  "uptime" gives load
  #      averages at 1, 5, and 15 minute marks.
  #
  local one=$(uptime | sed -e "s/.*load average: \(.*\...\), \(.*\...\), \(.*\...\)/\1/" -e "s/ //g")
  local five=$(uptime | sed -e "s/.*load average: \(.*\...\), \(.*\...\), \(.*\...\).*/\2/" -e "s/ //g")
  local diff1_5=$(echo -e "scale = scale ($one) \nx=$one - $five\n if (x>0) {print \"up\"} else {print \"down\"}\n print x \nquit \n" | bc)
  loaddiff="$(echo -n "${one}${diff1_5}")"

  #   Count visible files:
  let files=$(ls -l | grep "^-" | wc -l | tr -d " ")
  let hiddenfiles=$(ls -l -d .* | grep "^-" | wc -l | tr -d " ")
  let executables=$(ls -l | grep ^-..x | wc -l | tr -d " ")
  let directories=$(ls -l | grep "^d" | wc -l | tr -d " ")
  let hiddendirectories=$(ls -l -d .* | grep "^d" | wc -l | tr -d " ")-2
  let linktemp=$(ls -l | grep "^l" | wc -l | tr -d " ")
  if [ "$linktemp" -eq "0" ]
  then
      links=""
  else
      links=" ${linktemp}l"
  fi
  unset linktemp
  let devicetemp=$(ls -l | grep "^[bc]" | wc -l | tr -d " ")
  if [ "$devicetemp" -eq "0" ]
  then
      devices=""
  else
      devices=" ${devicetemp}bc"
  fi
  unset devicetemp

  }

  PROMPT_COMMAND=prompt_command

  function pprom2 {

  local        BLUE="\[\033[0;34m\]"
  local  LIGHT_GRAY="\[\033[0;37m\]"
  local LIGHT_GREEN="\[\033[1;32m\]"
  local  LIGHT_BLUE="\[\033[1;34m\]"
  local  LIGHT_CYAN="\[\033[1;36m\]"
  local      YELLOW="\[\033[1;33m\]"
  local       WHITE="\[\033[1;37m\]"
  local         RED="\[\033[0;31m\]"
  local   NO_COLOUR="\[\033[0m\]"

  case $TERM in
      xterm*)
          TITLEBAR='\[\033]0;\u@\h:\w\007\]'
          ;;
      *)
          TITLEBAR=""
          ;;
  esac

  PS1="$TITLEBAR\
  $BLUE[$RED\$(date +%H%M)$BLUE]\
  $BLUE[$RED\u@\h$BLUE]\
  $BLUE[\
  $LIGHT_GRAY\${files}.\${hiddenfiles}-\
  $LIGHT_GREEN\${executables}x \
  $LIGHT_GRAY(\${TotalMeg}Mb) \
  $LIGHT_BLUE\${directories}.\
  \${hiddendirectories}d\
  $LIGHT_CYAN\${links}\
  $YELLOW\${devices}\
  $BLUE]\
  $BLUE[${WHITE}\${loaddiff}$BLUE]\
  $BLUE[\
  $WHITE\$(ps ax | wc -l | sed -e \"s: ::g\")proc\
  $BLUE]\
  \n\
  $BLUE[$RED\$PWD$BLUE]\
  $WHITE\$\
  \
  $NO_COLOUR "
  PS2='> '
  PS4='+ '
  }
  ______________________________________________________________________




  10.4.  A Prompt the Width of Your Term

  A friend complained that he didn't like having a prompt that kept
  changing size because it had $PWD in it, so I wrote this prompt that
  adjusts its size to exactly the width of your term, with the working
  directory on the top line of two.


















  ______________________________________________________________________

  #!/bin/bash

  #   termwide prompt
  #      by Giles - created 2 November 98
  #
  #   The idea here is to have the upper line of this two line prompt
  #   always be the width of your term.  Do this by calculating the
  #   width of the text elements, and putting in fill as appropriate
  #   or right-truncating $PWD.
  #

  function prompt_command {

  TERMWIDTH=${COLUMNS}

  #   Calculate the width of the prompt:

  hostnam=$(echo -n $HOSTNAME | sed -e "s/[\.].*//")
  #   "whoami" and "pwd" include a trailing newline
  usernam=$(whoami)
  let usersize=$(echo -n $usernam | wc -c | tr -d " ")
  newPWD="${PWD}"
  let pwdsize=$(echo -n ${newPWD} | wc -c | tr -d " ")
  #   Add all the accessories below ...
  let promptsize=$(echo -n "--(${usernam}@${hostnam})---(${PWD})--" \
                   | wc -c | tr -d " ")
  let fillsize=${TERMWIDTH}-${promptsize}
  fill=""
  while [ "$fillsize" -gt "0" ]
  do
     fill="${fill}-"
     let fillsize=${fillsize}-1
  done

  if [ "$fillsize" -lt "0" ]
  then
     let cut=3-${fillsize}
     sedvar=""
     while [ "$cut" -gt "0" ]
     do
        sedvar="${sedvar}."
        let cut=${cut}-1
     done
     newPWD="...$(echo -n $PWD | sed -e "s/\(^${sedvar}\)\(.*\)/\2/")"
  fi
  }

  PROMPT_COMMAND=prompt_command

  function termwide {

  local GRAY="\[\033[1;30m\]"
  local LIGHT_GRAY="\[\033[0;37m\]"
  local WHITE="\[\033[1;37m\]"
  local NO_COLOUR="\[\033[0m\]"

  local LIGHT_BLUE="\[\033[1;34m\]"
  local YELLOW="\[\033[1;33m\]"

  case $TERM in
      xterm*)
          TITLEBAR='\[\033]0;\u@\h:\w\007\]'
          ;;
      *)
          TITLEBAR=""
          ;;
  esac

  PS1="$TITLEBAR\
  $YELLOW-$LIGHT_BLUE-(\
  $YELLOW\${usernam}$LIGHT_BLUE@$YELLOW\${hostnam}\
  ${LIGHT_BLUE})-${YELLOW}-\${fill}${LIGHT_BLUE}-(\
  $YELLOW\${newPWD}\
  $LIGHT_BLUE)-$YELLOW-\
  \n\
  $YELLOW-$LIGHT_BLUE-(\
  $YELLOW\$(date +%H%M)$LIGHT_BLUE:$YELLOW\$(date \"+%a,%d %b %y\")\
  $LIGHT_BLUE:$WHITE\$$LIGHT_BLUE)-\
  $YELLOW-\
  $NO_COLOUR "

  PS2="$LIGHT_BLUE-$YELLOW-$YELLOW-$NO_COLOUR "

  }
  ______________________________________________________________________




  10.5.  The Elegant Useless Clock Prompt

  This is probably the single most attractive (and useless) prompt I've
  ever created.  Because many X terminal emulators don't implement
  cursor position save and restore, the alternative when putting a clock
  in the upper right corner is to anchor the cursor at the bottom of the
  terminal.  This builds on the idea of the "termwide" prompt above,
  drawing a line up the right side of the screen from the prompt to the
  clock.  A VGA font is required.


  Note: There is an odd substitution in here, that may not print
  properly being translated from SGML to other formats: I had to
  substitute the screen character for \304 - I would normally have just
  included the sequence "\304", but it was necessary to make this
  substitution in this case.

























  ______________________________________________________________________

  #!/bin/bash

  #   This prompt requires a VGA font.  The prompt is anchored at the bottom
  #   of the terminal, fills the width of the terminal, and draws a line up
  #   the right side of the terminal to attach itself to a clock in the upper
  #   right corner of the terminal.

  function prompt_command {
  #   Calculate the width of the prompt:
  hostnam=$(echo -n $HOSTNAME | sed -e "s/[\.].*//")
  #   "whoami" and "pwd" include a trailing newline
  usernam=$(whoami)
  newPWD="${PWD}"
  #   Add all the accessories below ...
  let promptsize=$(echo -n "--(${usernam}@${hostnam})---(${PWD})-----" \
                   | wc -c | tr -d " ")
  #   Figure out how much to add between user@host and PWD (or how much to
  #   remove from PWD)
  let fillsize=${COLUMNS}-${promptsize}
  fill=""
  #   Make the filler if prompt isn't as wide as the terminal:
  while [ "$fillsize" -gt "0" ]
  do
     fill="${fill}Ä"
     # The A with the umlaut over it (it will appear as a long dash if
     # you're using a VGA font) is \304, but I cut and pasted it in
     # because Bash will only do one substitution - which in this case is
     # putting $fill in the prompt.
     let fillsize=${fillsize}-1
  done
  #   Right-truncate PWD if the prompt is going to be wider than the terminal:
  if [ "$fillsize" -lt "0" ]
  then
     let cutt=3-${fillsize}
     sedvar=""
     while [ "$cutt" -gt "0" ]
     do
        sedvar="${sedvar}."
        let cutt=${cutt}-1
     done
     newPWD="...$(echo -n $PWD | sed -e "s/\(^${sedvar}\)\(.*\)/\2/")"
  fi
  #
  #   Create the clock and the bar that runs up the right side of the term
  #
  local LIGHT_BLUE="\033[1;34m"
  local     YELLOW="\033[1;33m"
  #   Position the cursor to print the clock:
  echo -en "\033[2;$((${COLUMNS}-9))H"
  echo -en "$LIGHT_BLUE($YELLOW$(date +%H%M)$LIGHT_BLUE)\304$YELLOW\304\304\277"
  local i=${LINES}
  echo -en "\033[2;${COLUMNS}H"
  #   Print vertical dashes down the side of the terminal:
  while [ $i -ge 4 ]
  do
     echo -en "\033[$(($i-1));${COLUMNS}H\263"
     let i=$i-1
  done

  let prompt_line=${LINES}-1
  #   This is needed because doing \${LINES} inside a Bash mathematical
  #   expression (ie. $(())) doesn't seem to work.
  }

  PROMPT_COMMAND=prompt_command

  function clock3 {
  local LIGHT_BLUE="\[\033[1;34m\]"
  local     YELLOW="\[\033[1;33m\]"
  local      WHITE="\[\033[1;37m\]"
  local LIGHT_GRAY="\[\033[0;37m\]"
  local  NO_COLOUR="\[\033[0m\]"

  case $TERM in
      xterm*)
          TITLEBAR='\[\033]0;\u@\h:\w\007\]'
          ;;
      *)
          TITLEBAR=""
          ;;
  esac

  PS1="$TITLEBAR\
  \[\033[\${prompt_line};0H\]
  $YELLOW\332$LIGHT_BLUE\304(\
  $YELLOW\${usernam}$LIGHT_BLUE@$YELLOW\${hostnam}\
  ${LIGHT_BLUE})\304${YELLOW}\304\${fill}${LIGHT_BLUE}\304(\
  $YELLOW\${newPWD}\
  $LIGHT_BLUE)\304$YELLOW\304\304\304\331\
  \n\
  $YELLOW\300$LIGHT_BLUE\304(\
  $YELLOW\$(date \"+%a,%d %b %y\")\
  $LIGHT_BLUE:$WHITE\$$LIGHT_BLUE)\304\
  $YELLOW\304\
  $LIGHT_GRAY "

  PS2="$LIGHT_BLUE\304$YELLOW\304$YELLOW\304$NO_COLOUR "

  }
  ______________________________________________________________________






























