home *** CD-ROM | disk | FTP | other *** search
/ PC World 1999 August / PCWorld_1999-08_cd.bin / doc / HOWTO / Bash-Prompt-HOWTO < prev    next >
Text File  |  1999-02-08  |  61KB  |  2,047 lines

  1.   Bash Prompt HOWTO
  2.   Giles Orr, giles@interlog.com
  3.   v0.60, 07 January 1999
  4.  
  5.   Creating and controlling terminal and xterm prompts is discussed,
  6.   including incorporating standard escape sequences to give username,
  7.   current working directory, time, etc.  Further suggestions are made on
  8.   how to modify xterm title bars, use external functions to provide
  9.   prompt information, and how to use ANSI colours.
  10.   ______________________________________________________________________
  11.  
  12.   Table of Contents
  13.  
  14.  
  15.  
  16.  
  17.  
  18.  
  19.  
  20.  
  21.  
  22.  
  23.  
  24.  
  25.  
  26.  
  27.  
  28.  
  29.  
  30.  
  31.  
  32.  
  33.  
  34.  
  35.  
  36.  
  37.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.   1. Introduction and Administrivia
  68.  
  69.      1.1 Requirements
  70.      1.2 How To Use This Document
  71.      1.3 Translations
  72.      1.4 Problems
  73.      1.5 Send Me Comments and Suggestions
  74.      1.6 Credits
  75.      1.7 Copyright and Disclaimer
  76.  
  77.   2. Bash and Bash Prompts
  78.  
  79.      2.1 What is Bash?
  80.      2.2 What can tweaking your Bash Prompt do for you?
  81.      2.3 Why bother?
  82.      2.4 The First Step
  83.      2.5 Bash Prompt Escape Sequences
  84.      2.6 Setting the PS? Strings Permanently
  85.  
  86.   3. External Commands
  87.  
  88.      3.1 PROMPT_COMMAND
  89.      3.2 External Commands in the Prompt
  90.      3.3 What to Put in Your Prompt
  91.      3.4 Bash Environment and Functions
  92.  
  93.   4. Xterm Title Bar Manipulations
  94.  
  95.   5. ANSI Escape Sequences: Colours and Cursor Movement
  96.  
  97.      5.1 Colours
  98.      5.2 Cursor Movement
  99.      5.3 Moving the Cursor With tput
  100.  
  101.   6. Special Characters: Octal Escape Sequences
  102.  
  103.   7. The Bash Prompt Package
  104.  
  105.      7.1 Availability
  106.      7.2 Changing the Xterm Font
  107.  
  108.   8. Loading a Different Prompt
  109.  
  110.      8.1 Loading a Different Prompt, Later
  111.      8.2 Loading a Different Prompt, Immediately
  112.  
  113.   9. Loading Prompt Colours Dynamically
  114.  
  115.      9.1 A "Proof of Concept" Example
  116.  
  117.   10. Example Prompts
  118.  
  119.      10.1 A "Lightweight" Prompt
  120.      10.2 Elite from Bashprompt Themes
  121.      10.3 A "Power User" Prompt
  122.      10.4 A Prompt the Width of Your Term
  123.      10.5 The Elegant Useless Clock Prompt
  124.  
  125.  
  126.   ______________________________________________________________________
  127.  
  128.   1.  Introduction and Administrivia
  129.  
  130.  
  131.  
  132.  
  133.   1.1.  Requirements
  134.  
  135.   You will need Bash.  The default version on almost all Linux
  136.   distributions is 1.14.7 (as of this writing, November 98), which is a
  137.   well known and reliable shell.  Bash is now available in version 2.0+:
  138.   I've been using Bash 2.0 for a while now, but almost all code
  139.   presented here should work under 1.14.7.  If I'm aware of a problem,
  140.   I'll mention it.  You can check your Bash version by typing echo
  141.   $BASH_VERSION at the prompt.  On my machine, it responds with
  142.   2.02.1(1)-release.
  143.  
  144.  
  145.   Shell programming experience would be good, but isn't essential: the
  146.   more you know, the more complex prompts you'll be able to create.  I
  147.   assume a basic knowledge of shell programming and Unix utilities as I
  148.   go through this tutorial.  However, my own shell programming skills
  149.   are limited, so I give a lot of examples and explanation that may
  150.   appear unnecessary to an experienced shell programmer.
  151.  
  152.  
  153.   1.2.  How To Use This Document
  154.  
  155.   I include a lot of examples and explanatory text.  Different parts
  156.   will be of varying usefulness to different people.  This has grown
  157.   long enough that reading it straight through would be difficult - just
  158.   read the sections you need, backtrack as necessary.
  159.  
  160.  
  161.   1.3.  Translations
  162.  
  163.   As I write (6 January 99), translations are under weigh to both
  164.   Japanese (Akira Endo, akendo@t3.rim.or.jp) and German (Thomas Keil,
  165.   thomas@h-preissler.de).  Many thanks to both of them!  URLs will be
  166.   included when they become available.
  167.  
  168.  
  169.   1.4.  Problems
  170.  
  171.   This is a list of problems I've noticed while programming prompts.
  172.   Don't start reading here, and don't let this list discourage you -
  173.   these are mostly quite minor details.  Just check back if you run into
  174.   anything odd.
  175.  
  176.  
  177.   ╖  Many Bash features (such as math within $(()) among others) are
  178.      compile time options.  If you're using a binary distribution such
  179.      as comes with an standard Linux distribution, all such features
  180.      should be compiled in.  But if you're working on someone else's
  181.      system, this is worth keeping in mind if something you expected to
  182.      work doesn't.  Some notes about this in Learning the Bash Shell,
  183.      p.260-262.
  184.  
  185.   ╖  The terminal screen manager "screen" doesn't always get along with
  186.      ANSI colours.  I'm not a screen expert, unfortunately.  My current
  187.      version of screen (a very recent one) seems to work well in all
  188.      cases, but I've seen occasions where screen reduced all prompt
  189.      colours to the standard foreground colour in X terminals.  This
  190.      doesn't appear to be a problem on the console.
  191.  
  192.   ╖  Xdefaults files can override colours.  Look in  /.Xdefaults for
  193.      lines referring to XTerm*background and XTerm*foreground (or
  194.      possibly XTerm*Background and XTerm*Foreground).
  195.  
  196.   ╖  One of the prompts mentioned in this document uses the output of
  197.      "jobs" - as discussed at that time, "jobs" output to a pipe is
  198.      broken in Bash 2.02.
  199.   ╖  ANSI cursor movement escape sequences aren't all implemented in all
  200.      X terminals.  That's discussed in its own section.
  201.  
  202.   ╖  Some nice looking pseudo-graphics can be created by using a VGA
  203.      font rather than standard Linux fonts.  Unfortunately, these
  204.      effects look awful if you don't use a VGA font, and there's no way
  205.      to detect within a term what kind of font it's using.
  206.  
  207.   ╖  Bash 2.0+ is out, and it incorporates some new features, and
  208.      changes some behaviour.  Things that work under 1.14.7 don't
  209.      necessarily work the same under 2.0+, or vice versa.
  210.  
  211.  
  212.   1.5.  Send Me Comments and Suggestions
  213.  
  214.   This is a learning experience for me.  I've come to know a fair bit
  215.   about what can be done to create interesting and useful Bash Prompts,
  216.   but I need your input to correct and improve this document.  I've
  217.   tried to check suggestions I make against different versions of Bash
  218.   (mostly 2.02, which I use, and 1.14.7, which is in wide use), but let
  219.   me know of any incompatibilities you find.
  220.  
  221.  
  222.   The latest version of this document should always be available at
  223.   http://www.interlog.com/~giles/bashprompt.html.  Please check this
  224.   out, and feel free to e-mail me at giles@interlog.com with
  225.   suggestions.
  226.  
  227.  
  228.   I use the Linux Documentation Project HOWTOs almost exclusively in the
  229.   HTML format, so when I convert this from SGML, HTML is the only format
  230.   I check thoroughly.  If there are problems with other formats, I may
  231.   not know about them, and I'd appreciate a note about them.
  232.  
  233.  
  234.   1.6.  Credits
  235.  
  236.   In producing this document, I have borrowed heavily from the work of
  237.   the Bashprompt project at http://bash.current.nu/.  Other sources used
  238.   include the xterm Title mini-HOWTO by Ric Lister, available at
  239.   http://sunsite.unc.edu/LDP/HOWTO/mini/Xterm-Title.html, Ansi Prompts
  240.   by Keebler, available at http://www.ncal.verio.com/~keebler/ansi.html,
  241.   How to make a Bash Prompt Theme by Stephen Webb, available at
  242.   http://bash.current.nu/bash/HOWTO.html, and X ANSI Fonts by Stumpy,
  243.   available at http://home.earthlink.net/~us5zahns/enl/ansifont.html.
  244.  
  245.  
  246.   Also of immense help were several conversations and e-mails from Dan,
  247.   a co-worker at Georgia College & State University, whose knowledge of
  248.   Unix far exceeds mine.  He's given me several excellent suggestions,
  249.   and ideas of his have led to some interesting prompts.
  250.  
  251.  
  252.   Three books that have been very useful while programming prompts are
  253.   Linux in a Nutshell by Jessica Heckman Perry (O'Reilly, 1997),
  254.   Learning the Bash Shell by Cameron Newham and Bill Rosenblatt
  255.   (O'Reilly, 2nd. ed., 1998) and Unix Shell Programming by Lowell Jay
  256.   Arthur (Wiley, 1986.  This is the first edition, the fourth came out
  257.   in 1997).
  258.  
  259.  
  260.   1.7.  Copyright and Disclaimer
  261.  
  262.   This document is copyright 1998-1999 by Giles Orr.  You are encouraged
  263.   to redistribute it.  You may not modify this document (see the section
  264.   on contacting me: I have so far been incorporating all changes
  265.   recommended by readers).  Please contact me if you're interested in
  266.   doing a translation: that's one modification I can live with.
  267.  
  268.  
  269.   This document is available for free, and, while I have done the best I
  270.   can to make it accurate and up to date, I take no responsibility for
  271.   any problems you may encounter resulting from the use of this
  272.   document.
  273.  
  274.  
  275.   2.  Bash and Bash Prompts
  276.  
  277.   2.1.  What is Bash?
  278.  
  279.   Descended from the Bourne Shell, Bash is a GNU product, the "Bourne
  280.   Again SHell."  It's the standard command line interface on most Linux
  281.   machines.  It excels at interactivity, supporting command line
  282.   editing, completion, and recall.  It also supports configurable
  283.   prompts - most people realize this, but don't know how much can be
  284.   done.
  285.  
  286.  
  287.   2.2.  What can tweaking your Bash Prompt do for you?
  288.  
  289.   Most Linux systems have a default prompt in one colour (usually gray)
  290.   that tells you your user name, the name of the machine you're working
  291.   on, and some indication of your current working directory.  This is
  292.   all useful information, but you can do much more with the prompt: all
  293.   sorts of information can be displayed (tty number, time, date, load,
  294.   number of users, uptime ...) and the prompt can use ANSI colours,
  295.   either to make it look interesting, or to make certain information
  296.   stand out.  You can also manipulate the title bar of an Xterm to
  297.   reflect some of this information.
  298.  
  299.  
  300.   2.3.  Why bother?
  301.  
  302.   Beyond looking cool, it's often useful to keep track of system
  303.   information.  One idea that I know appeals to some people is that it
  304.   makes it possible to put prompts on different machines in different
  305.   colours.  If you have several Xterms open on several different
  306.   machines, or if you tend to forget what machine you're working on and
  307.   delete the wrong files, you'll find this a great way to remember what
  308.   machine you're on.
  309.  
  310.  
  311.   2.4.  The First Step
  312.  
  313.   The appearance of the prompt is governed by the shell variable PS1.
  314.   Command continuations are indicated by the PS2 string, which can be
  315.   modified in exactly the same ways discussed here - since controlling
  316.   it is exactly the same, and it isn't as "interesting," I'll mostly be
  317.   modifying the PS1 string.  (There are also PS3 and PS4 strings.  These
  318.   are never seen by the average user - see the Bash man page if you're
  319.   interested in their purpose.)  To change the way the prompt looks, you
  320.   change the PS1 variable.  For experimentation purposes, you can enter
  321.   the PS1 strings directly at the prompt, and see the results
  322.   immediately (this only affects your current session, and the changes
  323.   go away when you log out).  If you want to make a change to the prompt
  324.   permanent, modify your  /.bashrc file, and add the new definition of
  325.   PS1 there.  If you have root permissions, you can look in /etc/profile
  326.   and modify the "PS1=" line.  Be aware that on some distributions
  327.   (RedHat 5.1 at least) that the /etc/bashrc overrides the setting of
  328.   the PS1 and PS2 strings.
  329.  
  330.  
  331.   Before we get started, it's important to remember that the PS1 string
  332.   is stored in the environment like any other environment variable.  If
  333.   you modify it at the command line, your prompt will change.  Before
  334.   you make any changes, you can save your current prompt to another
  335.   environment variable:
  336.  
  337.  
  338.  
  339.        [giles@nikola giles]$ SAVE=$PS1
  340.        [giles@nikola giles]$
  341.  
  342.  
  343.  
  344.  
  345.  
  346.   The simplest prompt would be a single character, such as:
  347.  
  348.  
  349.  
  350.        [giles@nikola giles]$ PS1=$
  351.        $ls
  352.        bin   mail
  353.        $
  354.  
  355.  
  356.  
  357.  
  358.  
  359.   This demonstrates the best way to experiment with basic prompts,
  360.   entering them at the command line.  Notice that the text entered by
  361.   the user appears immediately after the prompt: I prefer to use
  362.  
  363.  
  364.  
  365.        $PS1="$ "
  366.        $ ls
  367.        bin   mail
  368.        $
  369.  
  370.  
  371.  
  372.  
  373.  
  374.   which forces a space after the prompt, making it more readable.  To
  375.   restore your original prompt, just call up the variable you stored:
  376.  
  377.  
  378.  
  379.        $ PS1=$SAVE
  380.        [giles@nikola giles]$
  381.  
  382.  
  383.  
  384.  
  385.  
  386.   2.5.  Bash Prompt Escape Sequences
  387.  
  388.   There are a lot of escape sequences offered by the Bash shell for
  389.   insertion in the prompt.  From the Bash 2.02 man page:
  390.  
  391.  
  392.  
  393.  
  394.  
  395.  
  396.  
  397.   When executing interactively, bash  displays  the  primary
  398.   prompt  PS1  when  it  is ready to read a command, and the
  399.   secondary prompt PS2 when it needs more input to  complete
  400.   a  command.   Bash  allows these prompt strings to be cus-
  401.   tomized by inserting a number of backslash-escaped special
  402.   characters that are decoded as follows:
  403.          \a     an ASCII bell character (07)
  404.          \d     the  date  in  "Weekday  Month  Date" format
  405.                 (e.g., "Tue May 26")
  406.          \e     an ASCII escape character (033)
  407.          \h     the hostname up to the first `.'
  408.          \H     the hostname
  409.          \n     newline
  410.          \r     carriage return
  411.          \s     the name of the shell, the  basename  of  $0
  412.                 (the portion following the final slash)
  413.          \t     the current time in 24-hour HH:MM:SS format
  414.          \T     the current time in 12-hour HH:MM:SS format
  415.          \@     the current time in 12-hour am/pm format
  416.          \u     the username of the current user
  417.          \v     the version of bash (e.g., 2.00)
  418.          \V     the  release  of  bash, version + patchlevel
  419.                 (e.g., 2.00.0)
  420.          \w     the current working directory
  421.          \W     the basename of the current  working  direc-
  422.                 tory
  423.          \!     the history number of this command
  424.          \#     the command number of this command
  425.          \$     if  the effective UID is 0, a #, otherwise a
  426.                 $
  427.          \nnn   the character  corresponding  to  the  octal
  428.                 number nnn
  429.          \\     a backslash
  430.          \[     begin a sequence of non-printing characters,
  431.                 which could be used to embed a terminal con-
  432.                 trol sequence into the prompt
  433.          \]     end a sequence of non-printing characters
  434.  
  435.  
  436.  
  437.  
  438.  
  439.   Continuing where we left off:
  440.  
  441.  
  442.  
  443.        [giles@nikola giles]$ PS1="\u@\h \W> "
  444.        giles@nikola giles> ls
  445.        bin   mail
  446.        giles@nikola giles>
  447.  
  448.  
  449.  
  450.  
  451.  
  452.   This is similar to the default on most Linux distributions.  I wanted
  453.   a slightly different appearance, so I changed this to:
  454.  
  455.  
  456.  
  457.        giles@nikola giles> PS1="[\t][\u@\h:\w]\$ "
  458.        [21:52:01][giles@nikola:~]$ ls
  459.        bin   mail
  460.        [21:52:15][giles@nikola:~]$
  461.  
  462.  
  463.   2.6.  Setting the PS? Strings Permanently
  464.  
  465.   Various people and distributions set their PS? strings in different
  466.   places.  The most common places are /etc/profile, /etc/bashrc,
  467.    /.bash_profile, and  /.bashrc .  Johan Kullstam (johan19@idt.net)
  468.   writes:
  469.  
  470.  
  471.  
  472.        the PS1 string should be set in .bashrc.  this is because
  473.        non-interactive bashes go out of their way to unset PS1.  the bash man
  474.        page tells how the presence or absence of PS1 is a good way of knowing
  475.        whether one is in an interactive vs non-interactive (ie script) bash
  476.        session.
  477.  
  478.        the way i realized this is that startx is a bash script.  what this
  479.        means is, startx will wipe out your prompt.  when you set PS1 in
  480.        .profile (or .bash_profile), login at console, fire up X via startx,
  481.        your PS1 gets nuked in the process leaving you with the default
  482.        prompt.
  483.  
  484.        one workaround is to launch xterms and rxvts with the -ls option to
  485.        force them to read .profile.  but any time a shell is called via a
  486.        non-interactive shell-script middleman PS1 is lost.  system(3) uses sh
  487.        -c which if sh is bash will kill PS1.  a better way is to place the
  488.        PS1 definition in .bashrc.  this is read every time bash starts and is
  489.        where interactive things - eg PS1 should go.
  490.  
  491.        therefore it should be stressed that PS1=..blah.. should be in .bashrc
  492.        and not .profile.
  493.  
  494.  
  495.  
  496.  
  497.  
  498.   I tried to duplicate the problem he explains, and encountered a
  499.   different one: my PROMPT_COMMAND variable (which will be introduced
  500.   later) was blown away.  My knowledge in this area is somewhat shaky,
  501.   so I'm going to go with what Johan says.
  502.  
  503.  
  504.   3.  External Commands
  505.  
  506.   3.1.  PROMPT_COMMAND
  507.  
  508.   Bash provides another environment variable called PROMPT_COMMAND.  The
  509.   contents of this variable are executed as a regular Bash command just
  510.   before Bash displays a prompt.
  511.  
  512.  
  513.  
  514.        [21:55:01][giles@nikola:~] PS1="[\u@\h:\w]\$ "
  515.        [giles@nikola:~] PROMPT_COMMAND="date +%H%M"
  516.        2155
  517.        [giles@nikola:~] d
  518.        bin   mail
  519.        2156
  520.        [giles@nikola:~]
  521.  
  522.  
  523.  
  524.  
  525.  
  526.   What happened above was that I changed PS1 to no longer include the \t
  527.   escape sequence, so the time was no longer a part of the prompt.  Then
  528.   I used date +%H%M to display the time in a format I like better.  But
  529.   it appears on a different line than the prompt.  Tidying this up using
  530.   echo -n ... as shown below works with Bash 2.0+, but appears not to
  531.   work with Bash 1.14.7: apparently the prompt is drawn in a different
  532.   way, and the following method results in overlapping text.
  533.  
  534.  
  535.  
  536.        2156
  537.        [giles@nikola:~] PROMPT_COMMAND="echo -n [$(date +%H%M)]"
  538.        [2156][giles@nikola:~]$
  539.        [2156][giles@nikola:~]$ d
  540.        bin   mail
  541.        [2157][giles@nikola:~]$ unset PROMPT_COMMAND
  542.        [giles@nikola:~]
  543.  
  544.  
  545.  
  546.  
  547.  
  548.   echo -n ... controls the output of the date command and supress the
  549.   trailing newline, allowing the prompt to appear all on one line.  At
  550.   the end, I used the unset command to remove the PROMPT_COMMAND
  551.   environment variable.
  552.  
  553.  
  554.   Note that I use the $(<command>) convention for command substitution:
  555.   that is,
  556.  
  557.  
  558.  
  559.        $(date +%H%M)
  560.  
  561.  
  562.  
  563.  
  564.  
  565.   means "substitute the output from the date +%H%M command here."  This
  566.   works in Bash 2.0+.  In some older versions of Bash, prior to 1.14.7,
  567.   you may need to use backquotes (`date +%H%M`).  Backquotes can be used
  568.   in Bash 2.0+, but are being phased out in favor of $(), which nests
  569.   better.  I will continue to use this convention throughout this
  570.   document.  If you're using an earlier version of Bash, you can usually
  571.   substitute backquotes where you see $().  If the command substitution
  572.   is escaped (ie. \$(command) ), then use backslashes to escape BOTH
  573.   your backquotes (ie. \'command\' ).
  574.  
  575.  
  576.   3.2.  External Commands in the Prompt
  577.  
  578.   You can use the output of regular Linux commands directly in the
  579.   prompt as well.  Obviously, you don't want to insert a lot of
  580.   material, or it will create a large prompt.  You also want to use a
  581.   fast command, because it's going to be executed every time your prompt
  582.   appears on the screen, and delays in the appearance of your prompt
  583.   while you're working can be very annoying.  (Unlike the previous
  584.   example that this closely resembles, this does work with Bash 1.14.7.)
  585.  
  586.  
  587.  
  588.        [21:58:33][giles@nikola:~]$ PS1="[\$(date +%H%M)][\u@\h:\w]\$ "
  589.        [2159][giles@nikola:~]$ ls
  590.        bin   mail
  591.        [2200][giles@nikola:~]$
  592.  
  593.  
  594.  
  595.   It's important to notice the backslash before the dollar sign of the
  596.   command substitution.  Without it, the external command is executed
  597.   exactly once: when the PS1 string is read into the environment.  For
  598.   this prompt, that would mean that it would display the same time no
  599.   matter how long the prompt was used.  The backslash protects the
  600.   contents of $() from immediate shell interpretation, so "date" is
  601.   called every time a prompt is generated.
  602.  
  603.  
  604.   Linux comes with a lot of small utility programs like date, grep, or
  605.   wc that allow you to manipulate data.  If you find yourself trying to
  606.   create complex combinations of these programs within a prompt, it may
  607.   be easier to make a shell script of your own, and call it from the
  608.   prompt.  Escape sequences are often required in bash shell scripts to
  609.   ensure that shell variables are expanded at the correct time (as seen
  610.   above with the date command): this is raised to another level within
  611.   the prompt PS1 line, and avoiding it by creating shell scripts is a
  612.   good idea.
  613.  
  614.  
  615.   An example of a small shell script used within a prompt is given
  616.   below:
  617.  
  618.  
  619.   ______________________________________________________________________
  620.   #!/bin/bash
  621.   #     lsbytesum - sum the number of bytes in a directory listing
  622.   TotalBytes=0
  623.   for Bytes in $(ls -l | grep "^-" | cut -c30-41)
  624.   do
  625.       let TotalBytes=$TotalBytes+$Bytes
  626.   done
  627.   TotalMeg=$(echo -e "scale=3 \n$TotalBytes/1048576 \nquit" | bc)
  628.   echo -n "$TotalMeg"
  629.   ______________________________________________________________________
  630.  
  631.  
  632.  
  633.  
  634.  
  635.   I have at times kept this both as a function (much more efficient -
  636.   unfortunately, explaining functions in detail is beyond the scope of
  637.   this document), or as a shell script in my  /bin directory, which is
  638.   on my path.  Used in a prompt:
  639.  
  640.  
  641.  
  642.        [2158][giles@nikola:~]$ PS1="[\u@\h:\w (\$(lsbytesum) Mb)]\$ "
  643.        [giles@nikola:~ (0 Mb)]$ cd /bin
  644.        [giles@nikola:/bin (4.498 Mb)]$
  645.  
  646.  
  647.  
  648.  
  649.  
  650.   3.3.  What to Put in Your Prompt
  651.  
  652.   You'll find I put username, machine name, time, and current directory
  653.   name in most of my prompts.  With the exception of the time, these are
  654.   very standard items to find in a prompt, and time is probably the next
  655.   most common addition.  But what you include is entirely a matter of
  656.   personal taste.  Here are examples from people I know to help give you
  657.   ideas.
  658.  
  659.  
  660.  
  661.   Dan's prompt is minimal but very effective, particularly for the way
  662.   he works.
  663.  
  664.  
  665.  
  666.        [giles@nikola:~]$ cur_tty=$(tty | sed -e "s/.*tty\(.*\)/\1/")
  667.        [giles@nikola:~]$ echo $cur_tty
  668.        p4
  669.        [giles@nikola:~]$ PS1="\!,$cur_tty,\$?\$ "
  670.        1095,p4,0$
  671.  
  672.  
  673.  
  674.  
  675.  
  676.   Dan doesn't like that having the current working directory can resize
  677.   the prompt drastically as you move through the directory tree, so he
  678.   keeps track of that in his head (or types "pwd").  He learned Unix
  679.   with csh and tcsh, so he uses his command history extensively
  680.   (something many of us weened on Bash do not do), so the first item in
  681.   the prompt is the history number.  The second item is the significant
  682.   characters of the tty (the output of "tty" is cropped with sed), an
  683.   item that can be useful to "screen" users.  The third item is the exit
  684.   value of the last command/pipeline (note that this is rendered useless
  685.   by any command executed within the prompt - you could work around that
  686.   by capturing it to a variable and playing it back, though).  Finally,
  687.   the "\$" is a dollar sign for a regular user, and switches to a hash
  688.   mark ("#") if the user is root.
  689.  
  690.  
  691.   Torben Fjerdingstad wrote to tell me that he often suspends jobs, and
  692.   then forgets about them, so he uses his prompt to remind him of
  693.   suspended jobs:
  694.  
  695.  
  696.  
  697.        [giles@nikola:~]$ function jobcount {
  698.        > jobs|wc -l| awk '{print $1}'
  699.        > }
  700.        [giles@nikola:~]$ export PS1='\W[`jobcount`]# '
  701.        giles[0]# man ls &
  702.        [1] 4150
  703.  
  704.        [1]+  Stopped (tty output)    man ls
  705.        giles[1]#
  706.  
  707.  
  708.  
  709.  
  710.  
  711.   Torben uses awk to trim the whitespace from the output of wc, while I
  712.   would have used sed or tr - not because they're better, but because
  713.   I'm more familiar with them.  There are probably other ways as well.
  714.   Torben also surrounds his PS1 string in single quotes, which prevent
  715.   Bash from immediately interpreting the backquotes, so he doesn't have
  716.   to escape them as I have mentioned.
  717.  
  718.  
  719.   NOTE: There is a known bug in Bash 2.02 that causes the jobs command
  720.   (a shell builtin) to return nothing to a pipe.  If you try the above
  721.   under Bash 2.02, you will always get a "0" back regardless of how many
  722.   jobs you have suspended.  Chet Ramey, one of the maintainers of Bash,
  723.   tells me that this will be fixed for v2.03.
  724.  
  725.  
  726.  
  727.   3.4.  Bash Environment and Functions
  728.  
  729.   As mentioned earlier, PS1, PS2, PS3, PS4, and PROMPT_COMMAND are all
  730.   stored in the Bash environment.  For those of us coming from a DOS
  731.   background, the idea of tossing big hunks of code into the environment
  732.   is horrifying, because that DOS environment was small, and didn't
  733.   exactly grow well.  There are probably practical limits on what you
  734.   can and should put in the environment, but I don't know what they are,
  735.   and we're probably talking a couple of orders of magnitude larger than
  736.   what DOS users are used to.  As Dan put it:
  737.  
  738.  
  739.   "In my interactive shell I have 62 aliases and 25 functions.  My rule
  740.   of thumb is that if I need something solely for interactive use and
  741.   can handily write it in bash I make it a shell function (assuming it
  742.   can't be easily expressed as an alias).  If these people are worried
  743.   about memory they don't need to be using bash.  Bash is one of the
  744.   largest programs I run on my linux box (outside of Oracle).  Run top
  745.   sometime and press 'M' to sort by memory - see how close bash is to
  746.   the top of the list.  Heck, it's bigger than sendmail!  Tell 'em to go
  747.   get ash or something."
  748.  
  749.  
  750.   I guess he was using console only the day he tried that: running X and
  751.   X apps, I have a lot of stuff larger than Bash.  But the idea is the
  752.   same: the environment is something to be used, and don't worry about
  753.   overfilling it.
  754.  
  755.  
  756.   I risk censure by Unix gurus when I say this (for the crime of over-
  757.   simplification), but functions are basically small shell scripts that
  758.   are loaded into the environment for the purpose of efficiency.
  759.   Quoting Dan again: "Shell functions are about as efficient as they can
  760.   be.  It is the approximate equivalent of sourcing a bash/bourne shell
  761.   script save that no file I/O need be done as the function is already
  762.   in memory.  The shell functions are typically loaded from [.bashrc or
  763.   .bash_profile] depending on whether you want them only in the initial
  764.   shell or in subshells as well.  Contrast this with running a shell
  765.   script: Your shell forks, the child does an exec, potentially the path
  766.   is searched, the kernel opens the file and examines enough bytes to
  767.   determine how to run the file, in the case of a shell script a shell
  768.   must be started with the name of the script as its argument, the shell
  769.   then opens the file, reads it and executes the statements.  Compared
  770.   to a shell function, everything other than executing the statments can
  771.   be considered unnecessary overhead."
  772.  
  773.  
  774.   4.  Xterm Title Bar Manipulations
  775.  
  776.   Non-printing escape sequences can be used to produce interesting
  777.   effects in prompts.  To use these escape sequences, you need to
  778.   enclose them in \[ and \], telling Bash to ignore this material while
  779.   calculating the size of the prompt.  Failing to include these
  780.   delimiters results in line editing code placing the cursor in the
  781.   wrong place because it doesn't know the actual size of the prompt.
  782.   Escape sequences must also be preceded by \033[ in Bash prior to
  783.   version 2, or by either \033[ or \e[ in later versions.
  784.  
  785.  
  786.   If you try to change the title bar of your Xterm with your prompt when
  787.   you're at the console, you'll produce garbage in your prompt.  To
  788.   avoid this, test the TERM environment variable to tell if your prompt
  789.   is going to be in an Xterm.
  790.  
  791.  
  792.  
  793.   ______________________________________________________________________
  794.   function proml
  795.   {
  796.   case $TERM in
  797.       xterm*)
  798.           local TITLEBAR='\[\033]0;\u@\h:\w\007\]'
  799.           ;;
  800.       *)
  801.           local TITLEBAR=''
  802.           ;;
  803.   esac
  804.  
  805.   PS1="${TITLEBAR}\
  806.   [\$(date +%H%M)]\
  807.   [\u@\h:\w]\
  808.   \$ "
  809.   PS2='> '
  810.   PS4='+ '
  811.   }
  812.   ______________________________________________________________________
  813.  
  814.  
  815.  
  816.  
  817.   This is a function that can be incorporated into  /.bashrc.  The
  818.   function name could then be called to execute the function.  The
  819.   function, like the PS1 string, is stored in the environment.  Once the
  820.   PS1 string is set by the function, you can remove the function from
  821.   the environment with unset proml.  Since the prompt can't change from
  822.   being in an Xterm to being at the console, the TERM variable isn't
  823.   tested every time the prompt is generated.  I used continuation
  824.   markers (backslashes) in the definition of the prompt, to allow it to
  825.   be continued on multiple lines. This improves readability, making it
  826.   easier to modify and debug.
  827.  
  828.  
  829.   I define this as a function because this is how the Bashprompt package
  830.   (discussed later in this document) deals with prompts: it's not the
  831.   only way to do it, but it works well.  As the prompts you use become
  832.   more complex, it becomes more and more cumbersome to type them in at
  833.   the prompt, and more practical to make them into some sort of text
  834.   file.  In this case, to test this at the prompt, save the above as a
  835.   text file called "proml".  You can work with it as follows:
  836.  
  837.  
  838.  
  839.        [giles@nikola:/bin (4.498 Mb)]$ cd          -> Go where you want to save the prompt
  840.        [giles@nikola:~ (0 Mb)]$ vi proml           -> Edit the prompt file
  841.        ...                                         -> Enter the text given above
  842.        [giles@nikola:~ (0 Mb)]$ source proml       -> Read the prompt function
  843.        [giles@nikola:~ (0 Mb)]$ proml              -> Execute the prompt function
  844.  
  845.  
  846.  
  847.  
  848.  
  849.   The first step in creating this prompt is to test if the shell we're
  850.   starting is an xterm or not: if it is, the shell variable
  851.   (${TITLEBAR}) is defined.  It consists of the appropriate escape
  852.   sequences, and \u@\h:\w, which puts <user>@<machine>:<working
  853.   directory> in the Xterm title bar.  This is particularily useful with
  854.   minimized Xterms, making them more rapidly identifiable.  The other
  855.   material in this prompt should be familiar from previous prompts we've
  856.   created.
  857.  
  858.  
  859.   The only drawback to manipulating the Xterm title bar like this occurs
  860.   when you log into a system on which you haven't set up the title bar
  861.   hack: the Xterm will continue to show the information from the
  862.   previous system that had the title bar hack in place.
  863.  
  864.  
  865.   5.  ANSI Escape Sequences: Colours and Cursor Movement
  866.  
  867.   5.1.  Colours
  868.  
  869.   As mentioned before, non-printing escape sequences have to be enclosed
  870.   in \[\033[ and \].  For colour escape sequences, they should also be
  871.   followed by a lowercase m.
  872.  
  873.  
  874.   If you try out the following prompts in an xterm and find that you
  875.   aren't seeing the colours named, check out your  /.Xdefaults file (and
  876.   possibly its bretheren) for lines like "XTerm*Foreground:
  877.   BlanchedAlmond".  This can be commented out by placing an exclamation
  878.   mark ("!") in front of it.  Of course, this will also be dependent on
  879.   what terminal emulator you're using.  This is the likeliest place that
  880.   your term foreground colours would be overridden.
  881.  
  882.  
  883.   To include blue text in the prompt:
  884.  
  885.  
  886.  
  887.        PS1="\[\033[34m\][\$(date +%H%M)][\u@\h:\w]$ "
  888.  
  889.  
  890.  
  891.  
  892.   The problem with this prompt is that the blue colour that starts with
  893.   the 34 colour code is never switched back to the regular colour, so
  894.   any text you type after the prompt is still in the colour of the
  895.   prompt.  This is also a dark shade of blue, so combining it with the
  896.   bold code might help:
  897.  
  898.  
  899.  
  900.        PS1="\[\033[1;34m\][\$(date +%H%M)][\u@\h:\w]$\[\033[0m\] "
  901.  
  902.  
  903.  
  904.  
  905.  
  906.   The prompt is now in light blue, and it ends by switching the colour
  907.   back to nothing (whatever foreground colour you had previously).
  908.  
  909.  
  910.   Here are the rest of the colour equivalences:
  911.  
  912.  
  913.  
  914.        Black       0;30     Dark Gray     1;30
  915.        Blue        0;34     Light Blue    1;34
  916.        Green       0;32     Light Green   1;32
  917.        Cyan        0;36     Light Cyan    1;36
  918.        Red         0;31     Light Red     1;31
  919.        Purple      0;35     Light Purple  1;35
  920.        Brown       0;33     Yellow        1;33
  921.        Light Gray  0;37     White         1;37
  922.  
  923.  
  924.  
  925.   You can also set background colours by using 44 for Blue background,
  926.   41 for a Red background, etc.  There are no bold background colours.
  927.   Combinations can be used, like Light Red text on a Blue background:
  928.   \[\033[44;1;31m\], although setting the colours separately seems to
  929.   work better (ie. \[\033[44m\]\[\033[1;31m\]).  Other codes available
  930.   include 4: Underscore, 5: Blink, 7: Inverse, and 8: Concealed.
  931.  
  932.  
  933.   Aside: Many people (myself included) object strongly to the "blink"
  934.   attribute.  Fortunately, it doesn't work in any terminal emulators
  935.   that I'm aware of - but it will still work on the console.  And, if
  936.   you were wondering (as I did) "What use is a 'Concealed' attribute?!"
  937.   - I saw it used in an example shell script (not a prompt) to allow
  938.   someone to type in a password without it being echoed to the screen.
  939.  
  940.  
  941.   Based on a prompt called "elite2" in the Bashprompt package (which I
  942.   have modified to work better on a standard console, rather than with
  943.   the special xterm fonts required to view the original properly), this
  944.   is a prompt I've used a lot:
  945.  
  946.  
  947.   ______________________________________________________________________
  948.  
  949.   function elite
  950.   {
  951.  
  952.   local GRAY="\[\033[1;30m\]"
  953.   local LIGHT_GRAY="\[\033[0;37m\]"
  954.   local CYAN="\[\033[0;36m\]"
  955.   local LIGHT_CYAN="\[\033[1;36m\]"
  956.  
  957.   case $TERM in
  958.       xterm*)
  959.           local TITLEBAR='\[\033]0;\u@\h:\w\007\]'
  960.           ;;
  961.       *)
  962.           local TITLEBAR=""
  963.           ;;
  964.   esac
  965.  
  966.   local GRAD1=$(tty|cut -d/ -f3)
  967.   PS1="$TITLEBAR\
  968.   $GRAY-$CYAN-$LIGHT_CYAN(\
  969.   $CYAN\u$GRAY@$CYAN\h\
  970.   $LIGHT_CYAN)$CYAN-$LIGHT_CYAN(\
  971.   $CYAN\#$GRAY/$CYAN$GRAD1\
  972.   $LIGHT_CYAN)$CYAN-$LIGHT_CYAN(\
  973.   $CYAN\$(date +%H%M)$GRAY/$CYAN\$(date +%d-%b-%y)\
  974.   $LIGHT_CYAN)$CYAN-$GRAY-\
  975.   $LIGHT_GRAY\n\
  976.   $GRAY-$CYAN-$LIGHT_CYAN(\
  977.   $CYAN\$$GRAY:$CYAN\w\
  978.   $LIGHT_CYAN)$CYAN-$GRAY-$LIGHT_GRAY "
  979.   PS2="$LIGHT_CYAN-$CYAN-$GRAY-$LIGHT_GRAY "
  980.   }
  981.   ______________________________________________________________________
  982.  
  983.  
  984.  
  985.  
  986.   I define the colours as temporary shell variables in the name of
  987.   readability.  It's easier to work with.  The "GRAD1" variable is a
  988.   check to determine what terminal you're on.  Like the test to
  989.   determine if you're working in an Xterm, it only needs to be done
  990.   once.  The prompt you see look like this, except in colour:
  991.        --(giles@nikola)-(75/ttyp7)-(1908/12-Oct-98)--
  992.        --($:~/tmp)--
  993.  
  994.  
  995.  
  996.  
  997.  
  998.   To help myself remember what colours are available, I wrote the
  999.   following script which echoes all the colours to screen:
  1000.  
  1001.  
  1002.  
  1003.  
  1004.  
  1005.  
  1006.  
  1007.  
  1008.  
  1009.  
  1010.  
  1011.  
  1012.  
  1013.  
  1014.  
  1015.  
  1016.  
  1017.  
  1018.  
  1019.  
  1020.  
  1021.  
  1022.  
  1023.  
  1024.  
  1025.  
  1026.  
  1027.  
  1028.  
  1029.  
  1030.  
  1031.  
  1032.  
  1033.  
  1034.  
  1035.  
  1036.  
  1037.  
  1038.  
  1039.  
  1040.  
  1041.  
  1042.  
  1043.  
  1044.  
  1045.  
  1046.  
  1047.  
  1048.  
  1049.  
  1050.  
  1051.  
  1052.  
  1053.  
  1054.  
  1055.  
  1056.  
  1057.   ______________________________________________________________________
  1058.   #!/bin/bash
  1059.   #
  1060.   #   This file echoes a bunch of colour codes to the terminal to demonstrate
  1061.   #   what's available.  Each line is one colour on black and gray
  1062.   #   backgrounds, with the code in the middle.  Verified to work on white,
  1063.   #   black, and green BGs (2 Dec 98).
  1064.   #
  1065.   echo "  On Light Gray:        On Black:"
  1066.   echo -e "\033[47m\033[1;37m  White        \033[0m\
  1067.    1;37m \
  1068.   \033[40m\033[1;37m  White        \033[0m"
  1069.   echo -e "\033[47m\033[37m  Light Gray   \033[0m\
  1070.      37m \
  1071.   \033[40m\033[37m  Light Gray   \033[0m"
  1072.   echo -e "\033[47m\033[1;30m  Gray         \033[0m\
  1073.    1;30m \
  1074.   \033[40m\033[1;30m  Gray         \033[0m"
  1075.   echo -e "\033[47m\033[30m  Black        \033[0m\
  1076.      30m \
  1077.   \033[40m\033[30m  Black        \033[0m"
  1078.   echo -e "\033[47m\033[31m  Red          \033[0m\
  1079.      31m \
  1080.   \033[40m\033[31m  Red          \033[0m"
  1081.   echo -e "\033[47m\033[1;31m  Light Red    \033[0m\
  1082.    1;31m \
  1083.   \033[40m\033[1;31m  Light Red    \033[0m"
  1084.   echo -e "\033[47m\033[32m  Green        \033[0m\
  1085.      32m \
  1086.   \033[40m\033[32m  Green        \033[0m"
  1087.   echo -e "\033[47m\033[1;32m  Light Green  \033[0m\
  1088.    1;32m \
  1089.   \033[40m\033[1;32m  Light Green  \033[0m"
  1090.   echo -e "\033[47m\033[33m  Brown        \033[0m\
  1091.      33m \
  1092.   \033[40m\033[33m  Brown        \033[0m"
  1093.   echo -e "\033[47m\033[1;33m  Yellow       \033[0m\
  1094.    1;33m \
  1095.   \033[40m\033[1;33m  Yellow       \033[0m"
  1096.   echo -e "\033[47m\033[34m  Blue         \033[0m\
  1097.      34m \
  1098.   \033[40m\033[34m  Blue         \033[0m"
  1099.   echo -e "\033[47m\033[1;34m  Light Blue   \033[0m\
  1100.    1;34m \
  1101.   \033[40m\033[1;34m  Light Blue   \033[0m"
  1102.   echo -e "\033[47m\033[35m  Purple       \033[0m\
  1103.      35m \
  1104.   \033[40m\033[35m  Purple       \033[0m"
  1105.   echo -e "\033[47m\033[1;35m  Pink         \033[0m\
  1106.    1;35m \
  1107.   \033[40m\033[1;35m  Pink         \033[0m"
  1108.   echo -e "\033[47m\033[36m  Cyan         \033[0m\
  1109.      36m \
  1110.   \033[40m\033[36m  Cyan         \033[0m"
  1111.   echo -e "\033[47m\033[1;36m  Light Cyan   \033[0m\
  1112.    1;36m \
  1113.   \033[40m\033[1;36m  Light Cyan   \033[0m"
  1114.   ______________________________________________________________________
  1115.  
  1116.  
  1117.  
  1118.  
  1119.   5.2.  Cursor Movement
  1120.  
  1121.   ANSI escape sequences allow you to move the cursor around the screen
  1122.   at will.  This is more useful for full screen user interfaces
  1123.   generated by shell scripts, but can also be used in prompts.  The
  1124.   movement escape sequences are as follows:
  1125.  
  1126.  
  1127.  
  1128.        - Position the Cursor:
  1129.          \033[<L>;<C>H
  1130.          puts the cursor at line L and column C.
  1131.        - Move the cursor up N lines:
  1132.          \033[<N>A
  1133.        - Move the cursor down N lines:
  1134.          \033[<N>B
  1135.        - Move the cursor forward N columns:
  1136.          \033[<N>C
  1137.        - Move the cursor backward N columns:
  1138.          \033[<N>D
  1139.  
  1140.        - Save cursor position:
  1141.          \033[s
  1142.        - Restore cursor position:
  1143.          \033[u
  1144.  
  1145.  
  1146.  
  1147.  
  1148.  
  1149.   The latter two codes are NOT honoured by many terminal emulators.  The
  1150.   only ones that I'm aware of that do are xterm and nxterm - even though
  1151.   the majority of terminal emulators are based on xterm code.  As far as
  1152.   I can tell, rxvt, kvt, xiterm, and Eterm do not support this.  They
  1153.   are supported on the console.
  1154.  
  1155.  
  1156.   Try putting in the following line of code at the prompt (it's a little
  1157.   clearer what it does if the prompt is several lines down the terminal
  1158.   when you put this in): echo -en "\033[7A\033[1;35m BASH
  1159.   \033[7B\033[6D" This should move the cursor seven lines up screen,
  1160.   print the word " BASH ", and then return to where it started to
  1161.   produce a normal prompt.  This isn't a prompt: it's just a
  1162.   demonstration of moving the cursor on screen, using colour to
  1163.   emphasize what has been done.
  1164.  
  1165.  
  1166.   Save this in a file called "clock":
  1167.  
  1168.  
  1169.  
  1170.  
  1171.  
  1172.  
  1173.  
  1174.  
  1175.  
  1176.  
  1177.  
  1178.  
  1179.  
  1180.  
  1181.  
  1182.  
  1183.  
  1184.  
  1185.  
  1186.  
  1187.  
  1188.  
  1189.   ______________________________________________________________________
  1190.   #!/bin/bash
  1191.  
  1192.   function prompt_command {
  1193.   let prompt_x=$COLUMNS-5
  1194.   }
  1195.  
  1196.   PROMPT_COMMAND=prompt_command
  1197.  
  1198.   function clock {
  1199.   local       BLUE="\[\033[0;34m\]"
  1200.   local        RED="\[\033[0;31m\]"
  1201.   local  LIGHT_RED="\[\033[1;31m\]"
  1202.   local      WHITE="\[\033[1;37m\]"
  1203.   local  NO_COLOUR="\[\033[0m\]"
  1204.   case $TERM in
  1205.       xterm*)
  1206.           TITLEBAR='\[\033]0;\u@\h:\w\007\]'
  1207.           ;;
  1208.       *)
  1209.           TITLEBAR=""
  1210.           ;;
  1211.   esac
  1212.  
  1213.   PS1="${TITLEBAR}\
  1214.   \[\033[s\033[1;\$(echo -n \${prompt_x})H\]\
  1215.   $BLUE[$LIGHT_RED\$(date +%H%M)$BLUE]\[\033[u\033[1A\]
  1216.   $BLUE[$LIGHT_RED\u@\h:\w$BLUE]\
  1217.   $WHITE\$$NO_COLOUR "
  1218.   PS2='> '
  1219.   PS4='+ '
  1220.   }
  1221.   ______________________________________________________________________
  1222.  
  1223.  
  1224.  
  1225.  
  1226.   This prompt is fairly plain, except that it keeps a 24 hour clock in
  1227.   the upper right corner of the terminal (even if the terminal is
  1228.   resized).  This will NOT work on the terminal emulators that I
  1229.   mentioned that don't accept the save and restore cursor position
  1230.   codes.  If you try to run this prompt in any of those terminal
  1231.   emulators, the clock will appear correctly, but the prompt will be
  1232.   trapped on the second line of the terminal.
  1233.  
  1234.  
  1235.   See also ``The Elegant Useless Clock Prompt'' for a more extensive use
  1236.   of these codes.
  1237.  
  1238.  
  1239.   5.3.  Moving the Cursor With tput
  1240.  
  1241.   As with so many things in Unix, there is more than one way to achieve
  1242.   the same ends.  A utility called "tput" can also be used to move the
  1243.   cursor around the screen, or get back information about the status of
  1244.   the terminal.  "tput" for cursor positioning is less flexible than
  1245.   ANSI escape sequences: you can only move the cursor to an absolute
  1246.   position, you can't move it relative to its current position.  I don't
  1247.   use "tput," so I'm not going to explain it in detail.  Type "man tput"
  1248.   and you'll know as much as I do.
  1249.  
  1250.  
  1251.   6.  Special Characters: Octal Escape Sequences
  1252.  
  1253.   Outside of the characters that you can type on your keyboard, there
  1254.   are a lot of other characters you can print on your screen.  I've
  1255.   created a script to allow you to check out what the font you're using
  1256.   has available for you.  The main command you need to use to utilise
  1257.   these characters is "echo -e".  The "-e" switch tells echo to enable
  1258.   interpretation of backslash-escaped characters.  What you see when you
  1259.   look at octal 200-400 will be very different with a VGA font from what
  1260.   you will see with a standard Linux font.  Be warned that some of these
  1261.   escape sequences have odd effects on your terminal, and I haven't
  1262.   tried to prevent them from doing whatever they do.  The linedraw and
  1263.   block characters (which many of us became familiar with with Word
  1264.   Perfect) that are used heavily by the Bashprompt project are between
  1265.   octal 260 and 337.
  1266.  
  1267.  
  1268.  
  1269.  
  1270.  
  1271.  
  1272.  
  1273.  
  1274.  
  1275.  
  1276.  
  1277.  
  1278.  
  1279.  
  1280.  
  1281.  
  1282.  
  1283.  
  1284.  
  1285.  
  1286.  
  1287.  
  1288.  
  1289.  
  1290.  
  1291.  
  1292.  
  1293.  
  1294.  
  1295.  
  1296.  
  1297.  
  1298.  
  1299.  
  1300.  
  1301.  
  1302.  
  1303.  
  1304.  
  1305.  
  1306.  
  1307.  
  1308.  
  1309.  
  1310.  
  1311.  
  1312.  
  1313.  
  1314.  
  1315.  
  1316.  
  1317.  
  1318.  
  1319.  
  1320.  
  1321.   ______________________________________________________________________
  1322.   #!/bin/bash
  1323.  
  1324.   #   Script: escgen
  1325.  
  1326.   function usage {
  1327.      echo -e "\033[1;34mescgen\033[0m <lower_octal_value> [<higher_octal_value>]"
  1328.      echo "   Octal escape sequence generator: print all octal escape sequences"
  1329.      echo "   between the lower value and the upper value.  If a second value"
  1330.      echo "   isn't supplied, print eight characters."
  1331.      echo "   1998 - Giles Orr, no warranty."
  1332.      exit 1
  1333.   }
  1334.  
  1335.   if [ "$#" -eq "0" ]
  1336.   then
  1337.      echo -e "\033[1;31mPlease supply one or two values.\033[0m"
  1338.      usage
  1339.   fi
  1340.   let lower_val=${1}
  1341.   if [ "$#" -eq "1" ]
  1342.   then
  1343.      #   If they don't supply a closing value, give them eight characters.
  1344.      upper_val=$(echo -e "obase=8 \n ibase=8 \n $lower_val+10 \n quit" | bc)
  1345.   else
  1346.      let upper_val=${2}
  1347.   fi
  1348.   if [ "$#" -gt "2" ]
  1349.   then
  1350.      echo -e "\033[1;31mPlease supply two values.\033[0m"
  1351.      echo
  1352.      usage
  1353.   fi
  1354.   if [ "${lower_val}" -gt "${upper_val}" ]
  1355.   then
  1356.      echo -e "\033[1;31m${lower_val} is larger than ${upper_val}."
  1357.      echo
  1358.      usage
  1359.   fi
  1360.   if [ "${upper_val}" -gt "777" ]
  1361.      then
  1362.      echo -e "\033[1;31mValues cannot exceed 777.\033[0m"
  1363.      echo
  1364.      usage
  1365.   fi
  1366.  
  1367.   let i=$lower_val
  1368.   let line_count=1
  1369.   let limit=$upper_val
  1370.   while [ "$i" -lt "$limit" ]
  1371.   do
  1372.      octal_escape="\\$i"
  1373.      echo -en "$i:'$octal_escape' "
  1374.      if [ "$line_count" -gt "7" ]
  1375.      then
  1376.         echo
  1377.         #   Put a hard return in.
  1378.         let line_count=0
  1379.      fi
  1380.      let i=$(echo -e "obase=8 \n ibase=8 \n $i+1 \n quit" | bc)
  1381.      let line_count=$line_count+1
  1382.   done
  1383.   echo
  1384.   ______________________________________________________________________
  1385.  
  1386.  
  1387.   You can also use xfd to display all the characters in an X font, with
  1388.   the command "xfd -fn <fontname>".  Clicking on any given character
  1389.   will give you lots of information about that character, including its
  1390.   octal value.  The script given above will be useful on the console,
  1391.   and if you aren't sure of the current font name.
  1392.  
  1393.  
  1394.   7.  The Bash Prompt Package
  1395.  
  1396.   7.1.  Availability
  1397.  
  1398.   The Bash Prompt package is available at http://bash.current.nu, and is
  1399.   the work of several people, co-ordinated by Rob Current (aka
  1400.   BadLandZ).  The package is an early beta, but offers a simple way of
  1401.   using multiple prompts (or themes), allowing you to set prompts for
  1402.   login shells, and for subshells (ie. putting PS1 strings in
  1403.    /.bash_profile and  /.bashrc).  Most of the themes use the extended
  1404.   VGA character set, so they look bad unless they're used with VGA fonts
  1405.   (which aren't the default on most systems).
  1406.  
  1407.  
  1408.   7.2.  Changing the Xterm Font
  1409.  
  1410.   To use some of the most attractive prompts in the Bash Prompt package,
  1411.   you need to get and install fonts that support the character sets
  1412.   expected by the prompts.  These are referred to as "VGA Fonts," but
  1413.   I'm unclear on the distinction between them and the fonts Linux
  1414.   usually ships with - although clearly they support different character
  1415.   sets.  Standard Xterm fonts support an extended alphabet, including a
  1416.   lot of letters with accents.  In VGA fonts, this material is replaced
  1417.   by graphical characters - blocks, dots, lines.  If anyone can explain
  1418.   this in more detail, e-mail me and I'll include the explanation here.
  1419.  
  1420.  
  1421.   Getting and installing these fonts is a somewhat involved process.
  1422.   First, retrieve the font(s).  Next, ensure they're .pcf or .pcf.gz
  1423.   files.  If they're .bdf files, investigate the "bdftopcf" command (ie.
  1424.   read the man page).  Drop the .pcf or .pcf.gz files into the
  1425.   /usr/X11R6/lib/X11/fonts/misc dir (this is the correct directory for
  1426.   RedHat 5.1 and Slackware 3.4, it may be different on other
  1427.   distributions).  "cd" to that directory, and run the "mkfontdir"
  1428.   command.  Then run "xset fp rehash".  Sometimes it's a good idea to go
  1429.   into the fonts.alias file in the same directory, and create shorter
  1430.   alias names for the fonts.
  1431.  
  1432.  
  1433.   To use the new fonts, you start your Xterm program of choice with the
  1434.   appropriate command to your Xterm, which can be found either in the
  1435.   man page or by using the "--help" parameter on the command line.
  1436.   Popular terms would be used as follows:
  1437.  
  1438.  
  1439.  
  1440.        xterm -font <fontname>
  1441.  
  1442.  
  1443.  
  1444.  
  1445.   OR
  1446.  
  1447.  
  1448.        xterm -fn <fontname> -fb <fontname-bold>
  1449.        Eterm -f <fontname>
  1450.        rxvt -fn <fontname>
  1451.  
  1452.  
  1453.   VGA fonts are available from Stumpy's ANSI Fonts page at
  1454.   http://home.earthlink.net/~us5zahns/enl/ansifont.html (which I have
  1455.   borrowed from extensively while writing this).
  1456.  
  1457.  
  1458.   8.  Loading a Different Prompt
  1459.  
  1460.   8.1.  Loading a Different Prompt, Later
  1461.  
  1462.   The explanations in this HOWTO have shown how to make PS1 environment
  1463.   variables, or how to incorporate those PS1 and PS2 strings into
  1464.   functions that could be called by  /.bashrc or as a theme by the
  1465.   bashprompt package.
  1466.  
  1467.  
  1468.   Using the bashprompt package, you would type bashprompt -i to see a
  1469.   list of available themes.  To set the prompt in future login shells
  1470.   (primarily the console, but also telnet and Xterms, depending on how
  1471.   your Xterms are set up), you would type bashprompt -l themename.
  1472.   bashprompt then modifies your  /.bash_profile to call the requested
  1473.   theme when it starts.  To set the prompt in future subshells (usually
  1474.   Xterms, rxvt, etc.), you type bashprompt -s themename, and bashprompt
  1475.   modifies your  /.bashrc file to call the appropriate theme at startup.
  1476.  
  1477.  
  1478.   See also ``Setting the PS? Strings Permanently'' for Johan Kullstam's
  1479.   note regarding the importance of putting the PS?  strings in  /.bashrc
  1480.   .
  1481.  
  1482.  
  1483.   8.2.  Loading a Different Prompt, Immediately
  1484.  
  1485.   You can change the prompt in your current terminal (using the example
  1486.   "elite" function above) by typing "source elite" followed by "elite"
  1487.   (assuming that the elite function file is the working directory).
  1488.   This is somewhat cumbersome, and leaves you with an extra function
  1489.   (elite) in your environment space - if you want to clean up the
  1490.   environment, you would have to type "unset elite" as well.  This would
  1491.   seem like an ideal candidate for a small shell script, but a script
  1492.   doesn't work here because the script cannot change the environment of
  1493.   your current shell: it can only change the environment of the subshell
  1494.   it runs in.  As soon as the script stops, the subshell goes away, and
  1495.   the changes the script made to the environment are gone.  What can
  1496.   change environment variables of your current shell are environment
  1497.   functions.  The bashprompt package puts a function called
  1498.   "callbashprompt" into your environment, and, while they don't document
  1499.   it, it can be called to load any bashprompt theme on the fly.  It
  1500.   looks in the theme directory it installed (the theme you're calling
  1501.   has to be there), sources the function you asked for, loads the
  1502.   function, and then unsets the function, thus keeping your environment
  1503.   uncluttered.  "callbashprompt" wasn't intended to be used this way,
  1504.   and has no error checking, but if you keep that in mind, it works
  1505.   quite well.
  1506.  
  1507.  
  1508.   9.  Loading Prompt Colours Dynamically
  1509.  
  1510.   9.1.  A "Proof of Concept" Example
  1511.  
  1512.   This is a "proof of concept" more than an attractive prompt: changing
  1513.   colours within the prompt dynamically.  In this example, the colour of
  1514.   the host name changes depending on the load (as a warning).
  1515.  
  1516.  
  1517.  
  1518.  
  1519.   ______________________________________________________________________
  1520.   #!/bin/bash
  1521.   #   "hostloadcolour" - 17 October 98, by Giles
  1522.   #
  1523.   #   The idea here is to change the colour of the host name in the prompt,
  1524.   #   depending on a threshold load value.
  1525.  
  1526.   # THRESHOLD_LOAD is the value of the one minute load (multiplied
  1527.   # by one hundred) at which you want
  1528.   # the prompt to change from COLOUR_LOW to COLOUR_HIGH
  1529.   THRESHOLD_LOAD=200
  1530.   COLOUR_LOW='1;34'
  1531.             # light blue
  1532.   COLOUR_HIGH='1;31'
  1533.              # light red
  1534.  
  1535.   function prompt_command {
  1536.   ONE=$(uptime | sed -e "s/.*load average: \(.*\...\), \(.*\...\), \(.*\...\)/\1/" -e "s/ //g")
  1537.   #   Apparently, "scale" in bc doesn't apply to multiplication, but does
  1538.   #   apply to division.
  1539.   ONEHUNDRED=$(echo -e "scale=0 \n $ONE/0.01 \nquit \n" | bc)
  1540.   if [ $ONEHUNDRED -gt $THRESHOLD_LOAD ]
  1541.   then
  1542.       HOST_COLOUR=$COLOUR_HIGH
  1543.           # Light Red
  1544.   else
  1545.       HOST_COLOUR=$COLOUR_LOW
  1546.           # Light Blue
  1547.   fi
  1548.   }
  1549.  
  1550.   function hostloadcolour {
  1551.  
  1552.   PROMPT_COMMAND=prompt_command
  1553.   PS1="[$(date +%H%M)][\u@\[\033[\$(echo -n \$HOST_COLOUR)m\]\h\[\033[0;37m\]:\w]$ "
  1554.   }
  1555.   ______________________________________________________________________
  1556.  
  1557.  
  1558.  
  1559.  
  1560.   Using your favorite editor, save this to a file named
  1561.   "hostloadcolour".  If you have the Bashprompt package installed, this
  1562.   will work as a theme.  If you don't, type source hostloadcolour and
  1563.   then hostloadcolour.  Either way, "prompt_command" becomes a function
  1564.   in your environment.  If you examine the code, you will notice that
  1565.   the colours ($COLOUR_HIGH and $COLOUR_LOW) are set using only a
  1566.   partial colour code, ie. "1;34" instead of "\[\033[1;34m\]", which I
  1567.   would have preferred.  I have been unable to get it to work with the
  1568.   complete code.  Please let me know if you manage this.
  1569.  
  1570.  
  1571.  
  1572.   10.  Example Prompts
  1573.  
  1574.   10.1.  A "Lightweight" Prompt
  1575.  
  1576.  
  1577.  
  1578.  
  1579.  
  1580.  
  1581.  
  1582.  
  1583.  
  1584.  
  1585.   ______________________________________________________________________
  1586.  
  1587.   function proml {
  1588.   local BLUE="\[\033[0;34m\]"
  1589.   local RED="\[\033[0;31m\]"
  1590.   local LIGHT_RED="\[\033[1;31m\]"
  1591.   local WHITE="\[\033[1;37m\]"
  1592.   local NO_COLOUR="\[\033[0m\]"
  1593.   case $TERM in
  1594.       xterm*)
  1595.           TITLEBAR='\[\033]0;\u@\h:\w\007\]'
  1596.           ;;
  1597.       *)
  1598.           TITLEBAR=""
  1599.           ;;
  1600.   esac
  1601.  
  1602.   PS1="${TITLEBAR}\
  1603.   $BLUE[$RED\$(date +%H%M)$BLUE]\
  1604.   $BLUE[$LIGHT_RED\u@\h:\w$BLUE]\
  1605.   $WHITE\$$NO_COLOUR "
  1606.   PS2='> '
  1607.   PS4='+ '
  1608.   }
  1609.   ______________________________________________________________________
  1610.  
  1611.  
  1612.  
  1613.  
  1614.   10.2.  Elite from Bashprompt Themes
  1615.  
  1616.   Note that this requires a VGA font.
  1617.  
  1618.  
  1619.   ______________________________________________________________________
  1620.  
  1621.   # Created by KrON from windowmaker on IRC
  1622.   # Changed by Spidey 08/06
  1623.   function elite {
  1624.   PS1="\[\033[31m\]\332\304\[\033[34m\](\[\033[31m\]\u\[\033[34m\]@\[\033[31m\]\h\
  1625.   \[\033[34m\])\[\033[31m\]-\[\033[34m\](\[\033[31m\]\$(date +%I:%M%P)\
  1626.   \[\033[34m\]-:-\[\033[31m\]\$(date +%m)\[\033[34m\033[31m\]/\$(date +%d)\
  1627.   \[\033[34m\])\[\033[31m\]\304-\[\033[34m]\\371\[\033[31m\]-\371\371\
  1628.   \[\033[34m\]\372\n\[\033[31m\]\300\304\[\033[34m\](\[\033[31m\]\W\[\033[34m\])\
  1629.   \[\033[31m\]\304\371\[\033[34m\]\372\[\033[00m\]"
  1630.   PS2="> "
  1631.   }
  1632.   ______________________________________________________________________
  1633.  
  1634.  
  1635.  
  1636.  
  1637.   10.3.  A "Power User" Prompt
  1638.  
  1639.   I actually do use this prompt, but it results in noticeable delays in
  1640.   the appearance of the prompt on a single-user PII-400, so I wouldn't
  1641.   recommend using it on a multi-user P-100 or anything ...  Look at it
  1642.   for ideas, rather than as a practical prompt.
  1643.  
  1644.  
  1645.  
  1646.  
  1647.  
  1648.  
  1649.  
  1650.  
  1651.   ______________________________________________________________________
  1652.  
  1653.   #!/bin/bash
  1654.   #----------------------------------------------------------------------
  1655.   #       POWER USER PROMPT "pprom2"
  1656.   #----------------------------------------------------------------------
  1657.   #
  1658.   #   Created August 98, Last Modified 9 November 98 by Giles
  1659.   #
  1660.   #   Problem: when load is going down, it says "1.35down-.08", get rid
  1661.   #   of the negative
  1662.  
  1663.   function prompt_command
  1664.   {
  1665.   #   Create TotalMeg variable: sum of visible file sizes in current directory
  1666.   local TotalBytes=0
  1667.   for Bytes in $(ls -l | grep "^-" | cut -c30-41)
  1668.   do
  1669.       let TotalBytes=$TotalBytes+$Bytes
  1670.   done
  1671.   TotalMeg=$(echo -e "scale=3 \nx=$TotalBytes/1048576\n if (x<1) {print \"0\"} \n print x \nquit" | bc)
  1672.  
  1673.   #      This is used to calculate the differential in load values
  1674.   #      provided by the "uptime" command.  "uptime" gives load
  1675.   #      averages at 1, 5, and 15 minute marks.
  1676.   #
  1677.   local one=$(uptime | sed -e "s/.*load average: \(.*\...\), \(.*\...\), \(.*\...\)/\1/" -e "s/ //g")
  1678.   local five=$(uptime | sed -e "s/.*load average: \(.*\...\), \(.*\...\), \(.*\...\).*/\2/" -e "s/ //g")
  1679.   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)
  1680.   loaddiff="$(echo -n "${one}${diff1_5}")"
  1681.  
  1682.   #   Count visible files:
  1683.   let files=$(ls -l | grep "^-" | wc -l | tr -d " ")
  1684.   let hiddenfiles=$(ls -l -d .* | grep "^-" | wc -l | tr -d " ")
  1685.   let executables=$(ls -l | grep ^-..x | wc -l | tr -d " ")
  1686.   let directories=$(ls -l | grep "^d" | wc -l | tr -d " ")
  1687.   let hiddendirectories=$(ls -l -d .* | grep "^d" | wc -l | tr -d " ")-2
  1688.   let linktemp=$(ls -l | grep "^l" | wc -l | tr -d " ")
  1689.   if [ "$linktemp" -eq "0" ]
  1690.   then
  1691.       links=""
  1692.   else
  1693.       links=" ${linktemp}l"
  1694.   fi
  1695.   unset linktemp
  1696.   let devicetemp=$(ls -l | grep "^[bc]" | wc -l | tr -d " ")
  1697.   if [ "$devicetemp" -eq "0" ]
  1698.   then
  1699.       devices=""
  1700.   else
  1701.       devices=" ${devicetemp}bc"
  1702.   fi
  1703.   unset devicetemp
  1704.  
  1705.   }
  1706.  
  1707.   PROMPT_COMMAND=prompt_command
  1708.  
  1709.   function pprom2 {
  1710.  
  1711.   local        BLUE="\[\033[0;34m\]"
  1712.   local  LIGHT_GRAY="\[\033[0;37m\]"
  1713.   local LIGHT_GREEN="\[\033[1;32m\]"
  1714.   local  LIGHT_BLUE="\[\033[1;34m\]"
  1715.   local  LIGHT_CYAN="\[\033[1;36m\]"
  1716.   local      YELLOW="\[\033[1;33m\]"
  1717.   local       WHITE="\[\033[1;37m\]"
  1718.   local         RED="\[\033[0;31m\]"
  1719.   local   NO_COLOUR="\[\033[0m\]"
  1720.  
  1721.   case $TERM in
  1722.       xterm*)
  1723.           TITLEBAR='\[\033]0;\u@\h:\w\007\]'
  1724.           ;;
  1725.       *)
  1726.           TITLEBAR=""
  1727.           ;;
  1728.   esac
  1729.  
  1730.   PS1="$TITLEBAR\
  1731.   $BLUE[$RED\$(date +%H%M)$BLUE]\
  1732.   $BLUE[$RED\u@\h$BLUE]\
  1733.   $BLUE[\
  1734.   $LIGHT_GRAY\${files}.\${hiddenfiles}-\
  1735.   $LIGHT_GREEN\${executables}x \
  1736.   $LIGHT_GRAY(\${TotalMeg}Mb) \
  1737.   $LIGHT_BLUE\${directories}.\
  1738.   \${hiddendirectories}d\
  1739.   $LIGHT_CYAN\${links}\
  1740.   $YELLOW\${devices}\
  1741.   $BLUE]\
  1742.   $BLUE[${WHITE}\${loaddiff}$BLUE]\
  1743.   $BLUE[\
  1744.   $WHITE\$(ps ax | wc -l | sed -e \"s: ::g\")proc\
  1745.   $BLUE]\
  1746.   \n\
  1747.   $BLUE[$RED\$PWD$BLUE]\
  1748.   $WHITE\$\
  1749.   \
  1750.   $NO_COLOUR "
  1751.   PS2='> '
  1752.   PS4='+ '
  1753.   }
  1754.   ______________________________________________________________________
  1755.  
  1756.  
  1757.  
  1758.  
  1759.   10.4.  A Prompt the Width of Your Term
  1760.  
  1761.   A friend complained that he didn't like having a prompt that kept
  1762.   changing size because it had $PWD in it, so I wrote this prompt that
  1763.   adjusts its size to exactly the width of your term, with the working
  1764.   directory on the top line of two.
  1765.  
  1766.  
  1767.  
  1768.  
  1769.  
  1770.  
  1771.  
  1772.  
  1773.  
  1774.  
  1775.  
  1776.  
  1777.  
  1778.  
  1779.  
  1780.  
  1781.  
  1782.  
  1783.   ______________________________________________________________________
  1784.  
  1785.   #!/bin/bash
  1786.  
  1787.   #   termwide prompt
  1788.   #      by Giles - created 2 November 98
  1789.   #
  1790.   #   The idea here is to have the upper line of this two line prompt
  1791.   #   always be the width of your term.  Do this by calculating the
  1792.   #   width of the text elements, and putting in fill as appropriate
  1793.   #   or right-truncating $PWD.
  1794.   #
  1795.  
  1796.   function prompt_command {
  1797.  
  1798.   TERMWIDTH=${COLUMNS}
  1799.  
  1800.   #   Calculate the width of the prompt:
  1801.  
  1802.   hostnam=$(echo -n $HOSTNAME | sed -e "s/[\.].*//")
  1803.   #   "whoami" and "pwd" include a trailing newline
  1804.   usernam=$(whoami)
  1805.   let usersize=$(echo -n $usernam | wc -c | tr -d " ")
  1806.   newPWD="${PWD}"
  1807.   let pwdsize=$(echo -n ${newPWD} | wc -c | tr -d " ")
  1808.   #   Add all the accessories below ...
  1809.   let promptsize=$(echo -n "--(${usernam}@${hostnam})---(${PWD})--" \
  1810.                    | wc -c | tr -d " ")
  1811.   let fillsize=${TERMWIDTH}-${promptsize}
  1812.   fill=""
  1813.   while [ "$fillsize" -gt "0" ]
  1814.   do
  1815.      fill="${fill}-"
  1816.      let fillsize=${fillsize}-1
  1817.   done
  1818.  
  1819.   if [ "$fillsize" -lt "0" ]
  1820.   then
  1821.      let cut=3-${fillsize}
  1822.      sedvar=""
  1823.      while [ "$cut" -gt "0" ]
  1824.      do
  1825.         sedvar="${sedvar}."
  1826.         let cut=${cut}-1
  1827.      done
  1828.      newPWD="...$(echo -n $PWD | sed -e "s/\(^${sedvar}\)\(.*\)/\2/")"
  1829.   fi
  1830.   }
  1831.  
  1832.   PROMPT_COMMAND=prompt_command
  1833.  
  1834.   function termwide {
  1835.  
  1836.   local GRAY="\[\033[1;30m\]"
  1837.   local LIGHT_GRAY="\[\033[0;37m\]"
  1838.   local WHITE="\[\033[1;37m\]"
  1839.   local NO_COLOUR="\[\033[0m\]"
  1840.  
  1841.   local LIGHT_BLUE="\[\033[1;34m\]"
  1842.   local YELLOW="\[\033[1;33m\]"
  1843.  
  1844.   case $TERM in
  1845.       xterm*)
  1846.           TITLEBAR='\[\033]0;\u@\h:\w\007\]'
  1847.           ;;
  1848.       *)
  1849.           TITLEBAR=""
  1850.           ;;
  1851.   esac
  1852.  
  1853.   PS1="$TITLEBAR\
  1854.   $YELLOW-$LIGHT_BLUE-(\
  1855.   $YELLOW\${usernam}$LIGHT_BLUE@$YELLOW\${hostnam}\
  1856.   ${LIGHT_BLUE})-${YELLOW}-\${fill}${LIGHT_BLUE}-(\
  1857.   $YELLOW\${newPWD}\
  1858.   $LIGHT_BLUE)-$YELLOW-\
  1859.   \n\
  1860.   $YELLOW-$LIGHT_BLUE-(\
  1861.   $YELLOW\$(date +%H%M)$LIGHT_BLUE:$YELLOW\$(date \"+%a,%d %b %y\")\
  1862.   $LIGHT_BLUE:$WHITE\$$LIGHT_BLUE)-\
  1863.   $YELLOW-\
  1864.   $NO_COLOUR "
  1865.  
  1866.   PS2="$LIGHT_BLUE-$YELLOW-$YELLOW-$NO_COLOUR "
  1867.  
  1868.   }
  1869.   ______________________________________________________________________
  1870.  
  1871.  
  1872.  
  1873.  
  1874.   10.5.  The Elegant Useless Clock Prompt
  1875.  
  1876.   This is probably the single most attractive (and useless) prompt I've
  1877.   ever created.  Because many X terminal emulators don't implement
  1878.   cursor position save and restore, the alternative when putting a clock
  1879.   in the upper right corner is to anchor the cursor at the bottom of the
  1880.   terminal.  This builds on the idea of the "termwide" prompt above,
  1881.   drawing a line up the right side of the screen from the prompt to the
  1882.   clock.  A VGA font is required.
  1883.  
  1884.  
  1885.   Note: There is an odd substitution in here, that may not print
  1886.   properly being translated from SGML to other formats: I had to
  1887.   substitute the screen character for \304 - I would normally have just
  1888.   included the sequence "\304", but it was necessary to make this
  1889.   substitution in this case.
  1890.  
  1891.  
  1892.  
  1893.  
  1894.  
  1895.  
  1896.  
  1897.  
  1898.  
  1899.  
  1900.  
  1901.  
  1902.  
  1903.  
  1904.  
  1905.  
  1906.  
  1907.  
  1908.  
  1909.  
  1910.  
  1911.  
  1912.  
  1913.  
  1914.  
  1915.   ______________________________________________________________________
  1916.  
  1917.   #!/bin/bash
  1918.  
  1919.   #   This prompt requires a VGA font.  The prompt is anchored at the bottom
  1920.   #   of the terminal, fills the width of the terminal, and draws a line up
  1921.   #   the right side of the terminal to attach itself to a clock in the upper
  1922.   #   right corner of the terminal.
  1923.  
  1924.   function prompt_command {
  1925.   #   Calculate the width of the prompt:
  1926.   hostnam=$(echo -n $HOSTNAME | sed -e "s/[\.].*//")
  1927.   #   "whoami" and "pwd" include a trailing newline
  1928.   usernam=$(whoami)
  1929.   newPWD="${PWD}"
  1930.   #   Add all the accessories below ...
  1931.   let promptsize=$(echo -n "--(${usernam}@${hostnam})---(${PWD})-----" \
  1932.                    | wc -c | tr -d " ")
  1933.   #   Figure out how much to add between user@host and PWD (or how much to
  1934.   #   remove from PWD)
  1935.   let fillsize=${COLUMNS}-${promptsize}
  1936.   fill=""
  1937.   #   Make the filler if prompt isn't as wide as the terminal:
  1938.   while [ "$fillsize" -gt "0" ]
  1939.   do
  1940.      fill="${fill}─"
  1941.      # The A with the umlaut over it (it will appear as a long dash if
  1942.      # you're using a VGA font) is \304, but I cut and pasted it in
  1943.      # because Bash will only do one substitution - which in this case is
  1944.      # putting $fill in the prompt.
  1945.      let fillsize=${fillsize}-1
  1946.   done
  1947.   #   Right-truncate PWD if the prompt is going to be wider than the terminal:
  1948.   if [ "$fillsize" -lt "0" ]
  1949.   then
  1950.      let cutt=3-${fillsize}
  1951.      sedvar=""
  1952.      while [ "$cutt" -gt "0" ]
  1953.      do
  1954.         sedvar="${sedvar}."
  1955.         let cutt=${cutt}-1
  1956.      done
  1957.      newPWD="...$(echo -n $PWD | sed -e "s/\(^${sedvar}\)\(.*\)/\2/")"
  1958.   fi
  1959.   #
  1960.   #   Create the clock and the bar that runs up the right side of the term
  1961.   #
  1962.   local LIGHT_BLUE="\033[1;34m"
  1963.   local     YELLOW="\033[1;33m"
  1964.   #   Position the cursor to print the clock:
  1965.   echo -en "\033[2;$((${COLUMNS}-9))H"
  1966.   echo -en "$LIGHT_BLUE($YELLOW$(date +%H%M)$LIGHT_BLUE)\304$YELLOW\304\304\277"
  1967.   local i=${LINES}
  1968.   echo -en "\033[2;${COLUMNS}H"
  1969.   #   Print vertical dashes down the side of the terminal:
  1970.   while [ $i -ge 4 ]
  1971.   do
  1972.      echo -en "\033[$(($i-1));${COLUMNS}H\263"
  1973.      let i=$i-1
  1974.   done
  1975.  
  1976.   let prompt_line=${LINES}-1
  1977.   #   This is needed because doing \${LINES} inside a Bash mathematical
  1978.   #   expression (ie. $(())) doesn't seem to work.
  1979.   }
  1980.  
  1981.   PROMPT_COMMAND=prompt_command
  1982.  
  1983.   function clock3 {
  1984.   local LIGHT_BLUE="\[\033[1;34m\]"
  1985.   local     YELLOW="\[\033[1;33m\]"
  1986.   local      WHITE="\[\033[1;37m\]"
  1987.   local LIGHT_GRAY="\[\033[0;37m\]"
  1988.   local  NO_COLOUR="\[\033[0m\]"
  1989.  
  1990.   case $TERM in
  1991.       xterm*)
  1992.           TITLEBAR='\[\033]0;\u@\h:\w\007\]'
  1993.           ;;
  1994.       *)
  1995.           TITLEBAR=""
  1996.           ;;
  1997.   esac
  1998.  
  1999.   PS1="$TITLEBAR\
  2000.   \[\033[\${prompt_line};0H\]
  2001.   $YELLOW\332$LIGHT_BLUE\304(\
  2002.   $YELLOW\${usernam}$LIGHT_BLUE@$YELLOW\${hostnam}\
  2003.   ${LIGHT_BLUE})\304${YELLOW}\304\${fill}${LIGHT_BLUE}\304(\
  2004.   $YELLOW\${newPWD}\
  2005.   $LIGHT_BLUE)\304$YELLOW\304\304\304\331\
  2006.   \n\
  2007.   $YELLOW\300$LIGHT_BLUE\304(\
  2008.   $YELLOW\$(date \"+%a,%d %b %y\")\
  2009.   $LIGHT_BLUE:$WHITE\$$LIGHT_BLUE)\304\
  2010.   $YELLOW\304\
  2011.   $LIGHT_GRAY "
  2012.  
  2013.   PS2="$LIGHT_BLUE\304$YELLOW\304$YELLOW\304$NO_COLOUR "
  2014.  
  2015.   }
  2016.   ______________________________________________________________________
  2017.  
  2018.  
  2019.  
  2020.  
  2021.  
  2022.  
  2023.  
  2024.  
  2025.  
  2026.  
  2027.  
  2028.  
  2029.  
  2030.  
  2031.  
  2032.  
  2033.  
  2034.  
  2035.  
  2036.  
  2037.  
  2038.  
  2039.  
  2040.  
  2041.  
  2042.  
  2043.  
  2044.  
  2045.  
  2046.  
  2047.