3082 lines
194 KiB
Plaintext
3082 lines
194 KiB
Plaintext
|
Bash Prompt HOWTO
|
|||
|
|
|||
|
$Revision: 0.93 $, $Date: 2003/11/06 02:12:02 $
|
|||
|
|
|||
|
Giles Orr
|
|||
|
|
|||
|
Copyright <20> 1998, 1999, 2000, 2001, 2003 Giles Orr
|
|||
|
|
|||
|
|
|||
|
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.
|
|||
|
|
|||
|
Permission is granted to copy, distribute and/or modify this document under
|
|||
|
the terms of the GNU Free Documentation License, Version 1.1 or any later
|
|||
|
version published by the Free Software Foundation; with no Invariant
|
|||
|
Sections, with no Front-Cover Texts, and with no Back-Cover Texts. A copy of
|
|||
|
the license is included in the section entitled "GNU Free Documentation
|
|||
|
License".
|
|||
|
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
Table of Contents
|
|||
|
1. Introduction and Administrivia
|
|||
|
1.1. Introduction
|
|||
|
1.2. Revision History
|
|||
|
1.3. Requirements
|
|||
|
1.4. How To Use This Document
|
|||
|
1.5. Document Versions, Comments and Suggestions
|
|||
|
1.6. Problems
|
|||
|
1.7. Credits/Bibliography
|
|||
|
1.8. 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. Bash Programming and Shell Scripts
|
|||
|
3.1. Variables
|
|||
|
3.2. Quotes and Special Characters
|
|||
|
3.3. Command Substitution
|
|||
|
3.4. Non-Printing Characters in Prompts
|
|||
|
3.5. Sourcing a File
|
|||
|
3.6. Functions, Aliases, and the Environment
|
|||
|
|
|||
|
|
|||
|
4. External Commands
|
|||
|
4.1. PROMPT_COMMAND
|
|||
|
4.2. External Commands in the Prompt
|
|||
|
4.3. What to Put in Your Prompt
|
|||
|
|
|||
|
|
|||
|
5. Saving Complex Prompts
|
|||
|
6. ANSI Escape Sequences: Colours and Cursor Movement
|
|||
|
6.1. Colours
|
|||
|
6.2. Cursor Movement
|
|||
|
6.3. Xterm Title Bar Manipulations
|
|||
|
6.4. Xterm Title Bars and Screen
|
|||
|
6.5. Colours and Cursor Movement With tput
|
|||
|
|
|||
|
|
|||
|
7. Special Characters: Octal Escape Sequences
|
|||
|
8. The Bash Prompt Package
|
|||
|
8.1. Availability
|
|||
|
8.2. Xterm Fonts
|
|||
|
8.3. Changing the Xterm Font
|
|||
|
8.4. Line Draw Characters without VGA Fonts
|
|||
|
|
|||
|
|
|||
|
9. Loading a Different Prompt
|
|||
|
9.1. Loading a Different Prompt, Later
|
|||
|
9.2. Loading a Different Prompt, Immediately
|
|||
|
9.3. Loading Different Prompts in Different X Terms
|
|||
|
|
|||
|
|
|||
|
10. Loading Prompt Colours Dynamically
|
|||
|
10.1. A "Proof of Concept" Example
|
|||
|
|
|||
|
|
|||
|
11. Prompt Code Snippets
|
|||
|
11.1. Built-in Escape Sequences
|
|||
|
11.2. Date and Time
|
|||
|
11.3. Counting Files in the Current Directory
|
|||
|
11.4. Total Bytes in the Current Directory
|
|||
|
11.5. Checking the Current TTY
|
|||
|
11.6. Stopped Jobs Count
|
|||
|
11.7. Load
|
|||
|
11.8. Uptime
|
|||
|
11.9. Number of Processes
|
|||
|
11.10. Controlling the Size and Appearance of $PWD
|
|||
|
11.11. Laptop Power
|
|||
|
11.12. Having the Prompt Ignored on Cut and Paste
|
|||
|
11.13. New Mail
|
|||
|
11.14. Prompt Beeps After Long-Running Commands
|
|||
|
|
|||
|
|
|||
|
12. Example Prompts
|
|||
|
12.1. Examples on the Web
|
|||
|
12.2. A "Lightweight" Prompt
|
|||
|
12.3. Dan's Prompt
|
|||
|
12.4. Elite from Bashprompt Themes
|
|||
|
12.5. A "Power User" Prompt
|
|||
|
12.6. Prompt Depending on Connection Type
|
|||
|
12.7. A Prompt the Width of Your Term
|
|||
|
12.8. The Floating Clock Prompt
|
|||
|
12.9. The Elegant Useless Clock Prompt
|
|||
|
|
|||
|
|
|||
|
A. GNU Free Documentation License
|
|||
|
0. PREAMBLE
|
|||
|
1. APPLICABILITY AND DEFINITIONS
|
|||
|
2. VERBATIM COPYING
|
|||
|
3. COPYING IN QUANTITY
|
|||
|
4. MODIFICATIONS
|
|||
|
5. COMBINING DOCUMENTS
|
|||
|
6. COLLECTIONS OF DOCUMENTS
|
|||
|
7. AGGREGATION WITH INDEPENDENT WORKS
|
|||
|
8. TRANSLATION
|
|||
|
9. TERMINATION
|
|||
|
10. FUTURE REVISIONS OF THIS LICENSE
|
|||
|
How to use this License for your documents
|
|||
|
|
|||
|
|
|||
|
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
Chapter 1. Introduction and Administrivia
|
|||
|
|
|||
|
1.1. Introduction
|
|||
|
|
|||
|
I've been maintaining this document for nearly six years (I believe the first
|
|||
|
submitted version was January 1998). I've received a lot of e-mail, almost
|
|||
|
all of it positive with a lot of great suggestions, and I've had a really
|
|||
|
good time doing this. Thanks to everyone for the support, suggestions, and
|
|||
|
translations!
|
|||
|
|
|||
|
I've had several requests both from individuals and the LDP group to issue a
|
|||
|
new version of this document, and it's long past due (two and a half years
|
|||
|
since the last version) - for which I apologize. Converting this monster to
|
|||
|
DocBook format was a daunting task, and then when I realized that I could now
|
|||
|
include images, I decided I needed to include all the cool examples that
|
|||
|
currently reside on my homepage. Adding these is a slow process, especially
|
|||
|
since I'm improving the code as I go, so only a few are included so far. This
|
|||
|
document will probably always feel incomplete to me ... I think however that
|
|||
|
it's reasonably sound from a technical point of view (although I have some
|
|||
|
mailed in fixes that aren't in here yet - if you've heard from me, they'll
|
|||
|
get in here eventually) so I'm going to post it and hope I can get to another
|
|||
|
version soon.
|
|||
|
|
|||
|
One other revision of note: this document (as requested by the LDP) is now
|
|||
|
under the GFDL. Enjoy.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
1.2. Revision History
|
|||
|
|
|||
|
Revision History
|
|||
|
Revision v0.93 2003-11-06
|
|||
|
Removal of very outdated "Translations" section.
|
|||
|
Revision v0.92 2003-11-06
|
|||
|
Added section on line draw in RXVT.
|
|||
|
Revision v0.91 2002-01-31
|
|||
|
Fixed text and code to "Total Bytes" snippet.
|
|||
|
Revision v0.90 2001-08-24 Revised by: go
|
|||
|
Added section on screen and Xterm titlebars.
|
|||
|
Revision v0.89 2001-08-20 Revised by: go
|
|||
|
Added clockt example, several example images added, improved laptop power
|
|||
|
code, minor tweaks.
|
|||
|
Revision v0.85 2001-07-31 Revised by: go
|
|||
|
Major revisions, plus change from Linuxdoc to DocBook.
|
|||
|
Revision v0.76 1999-12-31 Revised by: go
|
|||
|
Revision v0.60 1998-01-07 Revised by: go
|
|||
|
Initial public release?
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
1.3. Requirements
|
|||
|
|
|||
|
You will need Bash. This should be easy: it's the default shell for just
|
|||
|
about every Linux distribution I know of. The commonest version is now 2.0.x.
|
|||
|
Version 1.14.7 was the standard for a long time, but that started to fade
|
|||
|
around 2000. I've been using Bash 2.0.x for quite a while now. With recent
|
|||
|
revisions of the HOWTO (later than July 2001) I've been using a lot of code
|
|||
|
(mainly ${} substitutions) that I believe is specific to 2.x and may not work
|
|||
|
with Bash 1.x. You can check your Bash version by typing echo $BASH_VERSION
|
|||
|
at the prompt. On my machine, it responds with 2.05a.0(1)-release.
|
|||
|
|
|||
|
Shell programming experience would be good, but isn't essential: the more you
|
|||
|
know, the more complex the 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.4. 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.5. Document Versions, 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 no longer make code checks
|
|||
|
against older versions of Bash, let me know of any incompatibilities you
|
|||
|
find.
|
|||
|
|
|||
|
The latest version of this document should always be available at [http://
|
|||
|
www.gilesorr.com/bashprompt/] http://www.gilesorr.com/bashprompt/ (usually
|
|||
|
only in HTML format). The latest official release should always be at [http:/
|
|||
|
/www.tldp.org/] http://www.tldp.org/. Please check these out, and feel free
|
|||
|
to e-mail me at <giles at dreaming dot org> with suggestions.
|
|||
|
|
|||
|
I use the Linux Documentation Project HOWTOs almost exclusively in the HTML
|
|||
|
format, so when I convert this from DocBook SGML (its native format), 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.
|
|||
|
|
|||
|
There are issues with the PDF and RTF conversions (as of December 2000),
|
|||
|
including big problems with example code wrapping around the screen and
|
|||
|
getting mangled. I always keep my examples less than 80 characters wide, but
|
|||
|
the PDF version seems to wrap around 60. Please use online examples if the
|
|||
|
code in these versions don't work for you. But they do look very pretty.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
1.6. 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.
|
|||
|
|
|||
|
<EFBFBD><EFBFBD>*<2A>Many Bash features (such as math within $(()) among others) are compile
|
|||
|
time options. If you're using a binary distribution such as comes with a
|
|||
|
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 second edition, p.260-262.
|
|||
|
|
|||
|
<EFBFBD><EFBFBD>*<2A>The terminal screen manager "screen" doesn't always get along with ANSI
|
|||
|
colours. I'm not a screen expert, unfortunately. Versions older than
|
|||
|
3.7.6 may cause problems, but newer versions seem to work well in all
|
|||
|
cases. Old versions reduce all prompt colours to the standard foreground
|
|||
|
colour in X terminals.
|
|||
|
|
|||
|
<EFBFBD><EFBFBD>*<2A>Xdefaults files can override colours. Look in ~/.Xdefaults for lines
|
|||
|
referring to XTerm*background and XTerm*foreground (or possibly XTerm*
|
|||
|
Background and XTerm*Foreground).
|
|||
|
|
|||
|
<EFBFBD><EFBFBD>*<2A>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.
|
|||
|
|
|||
|
<EFBFBD><EFBFBD>*<2A>ANSI cursor movement escape sequences aren't all implemented in all X
|
|||
|
terminals. That's discussed in its own section.
|
|||
|
|
|||
|
<EFBFBD><EFBFBD>*<2A>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.
|
|||
|
|
|||
|
<EFBFBD><EFBFBD>*<2A>Things that work under Bash 1.14.7 don't necessarily work the same under
|
|||
|
2.0+, or vice versa.
|
|||
|
|
|||
|
<EFBFBD><EFBFBD>*<2A>I often use the code PS1="...\\$${NO_COLOUR} " at the end of my PS1
|
|||
|
string. The \\$ is replaced by a "$" for a normal user, and a "#" if you
|
|||
|
are root, and the ${NO_COLOUR} is an escape sequence that stops any
|
|||
|
colour modifications made by the prompt. However, I've had problems
|
|||
|
seeing the "#" when I'm root. I believe this is because Bash doesn't like
|
|||
|
two dollar signs in a row. Use PS1="...\\$ ${NO_COLOUR}" instead. I'm
|
|||
|
still trying to figure out how to get rid of that extra space.
|
|||
|
|
|||
|
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
1.7. Credits/Bibliography
|
|||
|
|
|||
|
In producing this document, I have borrowed heavily from the work of the
|
|||
|
Bashprompt project, which was at [http://bash.current.nu/] http://
|
|||
|
bash.current.nu/. This site was removed from its server as of July 2001 but
|
|||
|
Robert Current, the admin, assured me it would reappear soon. Unfortunately,
|
|||
|
it appears he's now (May 2003) let his domain registration lapse. The work of
|
|||
|
that project is carried on indirectly by Bashish (http://
|
|||
|
bashish.sourceforge.net/), with whom I've had no contact. Other sources used
|
|||
|
include the xterm Title mini-HOWTO by Ric Lister, available at [http://
|
|||
|
www.tldp.org/HOWTO/mini/Xterm-Title.html] http://www.tldp.org/HOWTO/mini/
|
|||
|
Xterm-Title.html, Ansi Prompts by Keebler, available at [http://
|
|||
|
www.ncal.verio.com/~keebler/ansi.html] http://www.ncal.verio.com/~keebler/
|
|||
|
ansi.html (now deceased), How to make a Bash Prompt Theme by Stephen Webb,
|
|||
|
available at [http://bash.current.nu/bash/HOWTO.html] http://bash.current.nu/
|
|||
|
bash/HOWTO.html (also deceased), and X ANSI Fonts by Stumpy, available at
|
|||
|
[http://home.earthlink.net/~us5zahns/enl/ansifont.html] http://
|
|||
|
home.earthlink.net/~us5zahns/enl/ansifont.html.
|
|||
|
|
|||
|
Also of immense help were several conversations and e-mails from Dan, who
|
|||
|
used to work at Georgia College & State University, whose knowledge of Unix
|
|||
|
far exceeded mine. He gave 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, 3rd ed., 2000), 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.8. Disclaimer
|
|||
|
|
|||
|
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.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
Chapter 2. Bash and Bash Prompts
|
|||
|
|
|||
|
2.1. What is Bash?
|
|||
|
|
|||
|
Descended from the Bourne Shell, Bash is a GNU product, the "Bourne Again SH
|
|||
|
ell." 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 (or shut down the server
|
|||
|
instead of the workstation), you'll find this a great way to remember what
|
|||
|
machine you're on.
|
|||
|
|
|||
|
For myself, I like the utility of having information about my machine and
|
|||
|
work environment available all the time. And I like the challenge of trying
|
|||
|
to figure out how to put the maximum amount of information into the smallest
|
|||
|
possible space while maintaining readability.
|
|||
|
|
|||
|
Perhaps the most practical aspect of colourizing your prompt is the ability
|
|||
|
to quickly spot the prompt when you use scrollback.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
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 exit the current shell). If you want to make a change to the
|
|||
|
prompt permanent, look at the section below Section 2.6.
|
|||
|
|
|||
|
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.04 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<75> |
|
|||
|
| tomized by inserting a number of backslash-escaped special |
|
|||
|
| characters that are decoded as follows: |
|
|||
|
| \a an ASCII bell character (07) |
|
|||
|
| \d the date in "Weekday Month Date" format |
|
|||
|
| (e.g., "Tue May 26") |
|
|||
|
| \e an ASCII escape character (033) |
|
|||
|
| \h the hostname up to the first `.' |
|
|||
|
| \H the hostname |
|
|||
|
| \j the number of jobs currently managed by the |
|
|||
|
| shell |
|
|||
|
| \l the basename of the shell's terminal device |
|
|||
|
| name |
|
|||
|
| \n newline |
|
|||
|
| \r carriage return |
|
|||
|
| \s the name of the shell, the basename of $0 |
|
|||
|
| (the portion following the final slash) |
|
|||
|
| \t the current time in 24-hour HH:MM:SS format |
|
|||
|
| \T the current time in 12-hour HH:MM:SS format |
|
|||
|
| \@ the current time in 12-hour am/pm format |
|
|||
|
| \u the username of the current user |
|
|||
|
| \v the version of bash (e.g., 2.00) |
|
|||
|
| \V the release of bash, version + patchlevel |
|
|||
|
| (e.g., 2.00.0) |
|
|||
|
| \w the current working directory |
|
|||
|
| \W the basename of the current working direc<65> |
|
|||
|
| 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<6F> |
|
|||
|
| trol sequence into the prompt |
|
|||
|
| \] end a sequence of non-printing characters |
|
|||
|
+---------------------------------------------------------------------------+
|
|||
|
|
|||
|
For long-time users, note the new \j and \l sequences: these are new in 2.03
|
|||
|
or 2.04.
|
|||
|
|
|||
|
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 at idt dot 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.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
Chapter 3. Bash Programming and Shell Scripts
|
|||
|
|
|||
|
3.1. Variables
|
|||
|
|
|||
|
I'm not going to try to explain all the details of Bash scripting in a
|
|||
|
section of this HOWTO, just the details pertaining to prompts. If you want to
|
|||
|
know more about shell programming and Bash in general, I highly recommend
|
|||
|
Learning the Bash Shell by Cameron Newham and Bill Rosenblatt (O'Reilly,
|
|||
|
1998). Oddly, my copy of this book is quite frayed. Again, I'm going to
|
|||
|
assume that you know a fair bit about Bash already. You can skip this section
|
|||
|
if you're only looking for the basics, but remember it and refer back if you
|
|||
|
proceed much farther.
|
|||
|
|
|||
|
Variables in Bash are assigned much as they are in any programming language:
|
|||
|
+---------------------------------------------------------------------------+
|
|||
|
|testvar=5 |
|
|||
|
|foo=zen |
|
|||
|
|bar="bash prompt" |
|
|||
|
+---------------------------------------------------------------------------+
|
|||
|
|
|||
|
Quotes are only needed in an assignment if a space (or special character,
|
|||
|
discussed shortly) is a part of the variable.
|
|||
|
|
|||
|
Variables are referenced slightly differently than they are assigned:
|
|||
|
+---------------------------------------------------------------------------+
|
|||
|
|> echo $testvar |
|
|||
|
|5 |
|
|||
|
|> echo $foo |
|
|||
|
|zen |
|
|||
|
|> echo ${bar} |
|
|||
|
|bash prompt |
|
|||
|
|> echo $NotAssigned |
|
|||
|
| |
|
|||
|
|> |
|
|||
|
+---------------------------------------------------------------------------+
|
|||
|
|
|||
|
A variable can be referred to as $bar or ${bar}. The braces are useful when
|
|||
|
it is unclear what is being referenced: if I write $barley do I mean ${bar}
|
|||
|
ley or ${barley}? Note also that referencing a value that hasn't been
|
|||
|
assigned doesn't generate an error, instead returning nothing.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
3.2. Quotes and Special Characters
|
|||
|
|
|||
|
If you wish to include a special character in a variable, you will have to
|
|||
|
quote it differently:
|
|||
|
+---------------------------------------------------------------------------+
|
|||
|
|> newvar=$testvar |
|
|||
|
|> echo $newvar |
|
|||
|
|5 |
|
|||
|
|> newvar="$testvar" |
|
|||
|
|> echo $newvar |
|
|||
|
|5 |
|
|||
|
|> newvar='$testvar' |
|
|||
|
|> echo $newvar |
|
|||
|
|$testvar |
|
|||
|
|> newvar=\$testvar |
|
|||
|
|> echo $newvar |
|
|||
|
|$testvar |
|
|||
|
|> |
|
|||
|
+---------------------------------------------------------------------------+
|
|||
|
|
|||
|
The dollar sign isn't the only character that's special to the Bash shell,
|
|||
|
but it's a simple example. An interesting step we can take to make use of
|
|||
|
assigning a variable name to another variable name is to use eval to
|
|||
|
dereference the stored variable name:
|
|||
|
+---------------------------------------------------------------------------+
|
|||
|
|> echo $testvar |
|
|||
|
|5 |
|
|||
|
|> echo $newvar |
|
|||
|
|$testvar |
|
|||
|
|> eval echo $newvar |
|
|||
|
|5 |
|
|||
|
|> |
|
|||
|
+---------------------------------------------------------------------------+
|
|||
|
|
|||
|
Normally, the shell does only one round of substitutions on the expression it
|
|||
|
is evaluating: if you say echo $newvar the shell will only go so far as to
|
|||
|
determine that $newvar is equal to the text string $testvar, it won't
|
|||
|
evaluate what $testvar is equal to. eval forces that evaluation.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
3.3. Command Substitution
|
|||
|
|
|||
|
In almost all cases in this document, 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. 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.4. Non-Printing Characters in Prompts
|
|||
|
|
|||
|
Many of the changes that can be made to Bash prompts that are discussed in
|
|||
|
this HOWTO use non-printing characters. Changing the colour of the prompt
|
|||
|
text, changing an Xterm title bar, and moving the cursor position all require
|
|||
|
non-printing characters.
|
|||
|
|
|||
|
If I want a very simple prompt consisting of a greater-than sign and a space:
|
|||
|
+---------------------------------------------------------------------------+
|
|||
|
|[giles@nikola giles]$ PS1='> ' |
|
|||
|
|> |
|
|||
|
+---------------------------------------------------------------------------+
|
|||
|
|
|||
|
This is just a two character prompt. If I modify it so that it's a bright
|
|||
|
yellow greater-than sign (colours are discussed in their own section):
|
|||
|
+---------------------------------------------------------------------------+
|
|||
|
|> PS1='\033[1;33m>\033[0m ' |
|
|||
|
|> |
|
|||
|
+---------------------------------------------------------------------------+
|
|||
|
|
|||
|
This works fine - until you type in a large command line. Because the prompt
|
|||
|
still only consists of two printing characters (a greater-than sign and a
|
|||
|
space) but the shell thinks that this prompt is eleven characters long (I
|
|||
|
think it counts '\033' , '[1' and '[0' as one character each). You can see
|
|||
|
this by typing a really long command line - you will find that the shell
|
|||
|
wraps the text before it gets to the edge of the terminal, and in most cases
|
|||
|
wraps it badly. This is because it's confused about the actual length of the
|
|||
|
prompt.
|
|||
|
|
|||
|
So use this instead:
|
|||
|
+---------------------------------------------------------------------------+
|
|||
|
|> PS1='\[\033[1;33m\]>\[\033[0m\] ' |
|
|||
|
+---------------------------------------------------------------------------+
|
|||
|
|
|||
|
This is more complex, but it works. Command lines wrap properly. What's been
|
|||
|
done is to enclose the '\033[1;33m' that starts the yellow colour in '\[' and
|
|||
|
'\]' which tells the shell "everything between these escaped square brackets,
|
|||
|
including the brackets themselves, is a non-printing character." The same is
|
|||
|
done with the '\033[0m' that ends the colour.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
3.5. Sourcing a File
|
|||
|
|
|||
|
When a file is sourced (by typing either source filename or . filename at the
|
|||
|
command line), the lines of code in the file are executed as if they were
|
|||
|
printed at the command line. This is particularly useful with complex
|
|||
|
prompts, to allow them to be stored in files and called up by sourcing the
|
|||
|
file they are in.
|
|||
|
|
|||
|
In examples, you will find that I often include #!/bin/bash at the beginning
|
|||
|
of files including functions. This is not necessary if you are sourcing a
|
|||
|
file, just as it isn't necessary to chmod +x a file that is going to be
|
|||
|
sourced. I do this because it makes Vim (my editor of choice, no flames
|
|||
|
please - you use what you like) think I'm editing a shell script and turn on
|
|||
|
colour syntax highlighting.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
3.6. Functions, Aliases, and the Environment
|
|||
|
|
|||
|
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 to 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
|
|||
|
statements can be considered unnecessary overhead."
|
|||
|
|
|||
|
Aliases are simple to create:
|
|||
|
+---------------------------------------------------------------------------+
|
|||
|
|alias d="ls --color=tty --classify" |
|
|||
|
|alias v="d --format=long" |
|
|||
|
|alias rm="rm -i" |
|
|||
|
+---------------------------------------------------------------------------+
|
|||
|
|
|||
|
Any arguments you pass to the alias are passed to the command line of the
|
|||
|
aliased command (ls in the first two cases). Note that aliases can be nested,
|
|||
|
and they can be used to make a normal unix command behave in a different way.
|
|||
|
(I agree with the argument that you shouldn't use the latter kind of aliases
|
|||
|
- if you get in the habit of relying on "rm *" to ask you if you're sure, you
|
|||
|
may lose important files on a system that doesn't use your alias.)
|
|||
|
|
|||
|
Functions are used for more complex program structures. As a general rule,
|
|||
|
use an alias for anything that can be done in one line. Functions differ from
|
|||
|
shell scripts in that they are loaded into the environment so that they work
|
|||
|
more quickly. As a general rule again, you would want to keep functions
|
|||
|
relatively small, and any shell script that gets relatively large should
|
|||
|
remain a shell script rather than turning it into a function. Your decision
|
|||
|
to load something as a function is also going to depend on how often you use
|
|||
|
it. If you use a small shell script infrequently, leave it as a shell script.
|
|||
|
If you use it often, turn it into a function.
|
|||
|
|
|||
|
To modify the behaviour of ls, you could do something like the following:
|
|||
|
+---------------------------------------------------------------------------+
|
|||
|
|function lf |
|
|||
|
|{ |
|
|||
|
| ls --color=tty --classify $* |
|
|||
|
| echo "$(ls -l $* | wc -l) files" |
|
|||
|
|} |
|
|||
|
+---------------------------------------------------------------------------+
|
|||
|
|
|||
|
This could readily be set as an alias, but for the sake of example, we'll
|
|||
|
make it a function. If you type the text shown into a text file and then
|
|||
|
source that file, the function will be in your environment, and be
|
|||
|
immediately available at the command line without the overhead of a shell
|
|||
|
script mentioned previously. The usefulness of this becomes more obvious if
|
|||
|
you consider adding more functionality to the above function, such as using
|
|||
|
an if statement to execute some special code when links are found in the
|
|||
|
listing.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
Chapter 4. External Commands
|
|||
|
|
|||
|
4.1. PROMPT_COMMAND
|
|||
|
|
|||
|
Bash provides an environment variable called PROMPT_COMMAND. The contents of
|
|||
|
this variable are executed as a regular Bash command just before Bash
|
|||
|
displays a prompt.
|
|||
|
+---------------------------------------------------------------------------+
|
|||
|
|[21:55:01][giles@nikola:~] PS1="[\u@\h:\w]\$ " |
|
|||
|
|[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 (added in a previous section), 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 suppresses 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.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
4.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 an
|
|||
|
alias, function, or 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 functions 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 "^-" | awk '{ print $5 }')
|
|||
|
do
|
|||
|
let TotalBytes=$TotalBytes+$Bytes
|
|||
|
done
|
|||
|
TotalMeg=$(echo -e "scale=3 \n$TotalBytes/1048576 \nquit" | bc)
|
|||
|
echo -n "$TotalMeg"
|
|||
|
|
|||
|
I used to keep this as a function, it now lives 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)]$ |
|
|||
|
+---------------------------------------------------------------------------+
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
4.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
|
|||
|
is an interesting example to help give you ideas.
|
|||
|
|
|||
|
Dan's prompt is minimal but very effective, particularly for the way he
|
|||
|
works.
|
|||
|
+---------------------------------------------------------------------------+
|
|||
|
|[giles@nikola:~]$ PS1="\!,\l,\$?\$ " |
|
|||
|
|1095,4,0$ non-command |
|
|||
|
|bash: non-command: command not found |
|
|||
|
|1096,4,127$ |
|
|||
|
+---------------------------------------------------------------------------+
|
|||
|
|
|||
|
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 weaned on Bash
|
|||
|
do not do), so the first item in the prompt is the history number. The second
|
|||
|
item is the tty number, 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 can 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.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
Chapter 5. Saving Complex Prompts
|
|||
|
|
|||
|
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. I have adopted the method used by the Bashprompt
|
|||
|
package (discussed later in this document: Chapter 8), which is to put the
|
|||
|
primary commands for the prompt in one file with the PS1 string in particular
|
|||
|
defined within a function of the same name as the file itself. It's not the
|
|||
|
only way to do it, but it works well. Take the following example:
|
|||
|
+---------------------------------------------------------------------------+
|
|||
|
|#!/bin/bash |
|
|||
|
| |
|
|||
|
|function tonka { |
|
|||
|
| |
|
|||
|
|# Named "Tonka" because of the colour scheme |
|
|||
|
| |
|
|||
|
|local WHITE="\[\033[1;37m\]" |
|
|||
|
|local LIGHT_BLUE="\[\033[1;34m\]" |
|
|||
|
|local YELLOW="\[\033[1;33m\]" |
|
|||
|
|local NO_COLOUR="\[\033[0m\]" |
|
|||
|
| |
|
|||
|
|case $TERM in |
|
|||
|
| xterm*|rxvt*) |
|
|||
|
| TITLEBAR='\[\033]0;\u@\h:\w\007\]' |
|
|||
|
| ;; |
|
|||
|
| *) |
|
|||
|
| TITLEBAR="" |
|
|||
|
| ;; |
|
|||
|
|esac |
|
|||
|
| |
|
|||
|
|PS1="$TITLEBAR\ |
|
|||
|
|$YELLOW-$LIGHT_BLUE-(\ |
|
|||
|
|$YELLOW\u$LIGHT_BLUE@$YELLOW\h\ |
|
|||
|
|$LIGHT_BLUE)-(\ |
|
|||
|
|$YELLOW\$PWD\ |
|
|||
|
|$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 " |
|
|||
|
| |
|
|||
|
|} |
|
|||
|
+---------------------------------------------------------------------------+
|
|||
|
|
|||
|
You can work with it as follows:
|
|||
|
+---------------------------------------------------------------------------+
|
|||
|
|[giles@nikola:/bin (4.498 Mb)]$ cd (1) |
|
|||
|
|[giles@nikola:~ (0 Mb)]$ vim tonka (2) |
|
|||
|
|... (3) |
|
|||
|
|[giles@nikola:~ (0 Mb)]$ source tonka (4) |
|
|||
|
|[giles@nikola:~ (0 Mb)]$ tonka (5) |
|
|||
|
|[giles@nikola:~ (0 Mb)]$ unset tonka (6) |
|
|||
|
+---------------------------------------------------------------------------+
|
|||
|
|
|||
|
(1) Move to the directory where you want to save the prompt
|
|||
|
(2) Edit the prompt file with your preferred editor
|
|||
|
(3) Enter the prompt text given above as "tonka"
|
|||
|
(4) Read the prompt function into the environment
|
|||
|
(5) Execute the prompt function
|
|||
|
(6) Optionally, unclutter your environment by unsetting the function
|
|||
|
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
Chapter 6. ANSI Escape Sequences: Colours and Cursor Movement
|
|||
|
|
|||
|
6.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 |
|
|||
|
+---------------------------------------------------------------------------+
|
|||
|
|
|||
|
Daniel Dui (ddui@iee.org) points out that to be strictly accurate, we must
|
|||
|
mention that the list above is for colours at the console. In an xterm, the
|
|||
|
code 1;31 isn't "Light Red," but "Bold Red." This is true of all the colours.
|
|||
|
|
|||
|
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.
|
|||
|
|
|||
|
Note Many people (myself included) object strongly to the "blink" attribute
|
|||
|
because it's extremely distracting and irritating. Fortunately, it
|
|||
|
doesn't work in any terminal emulators that I'm aware of - but it will
|
|||
|
still work on the console.
|
|||
|
|
|||
|
Note 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.
|
|||
|
However, this attribute doesn't seem to be honoured by many terms other
|
|||
|
than "Xterm."
|
|||
|
|
|||
|
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\]"
|
|||
|
local NO_COLOUR="\[\033[0m\]"
|
|||
|
|
|||
|
case $TERM in
|
|||
|
xterm*|rxvt*)
|
|||
|
local TITLEBAR='\[\033]0;\u@\h:\w\007\]'
|
|||
|
;;
|
|||
|
*)
|
|||
|
local TITLEBAR=""
|
|||
|
;;
|
|||
|
esac
|
|||
|
|
|||
|
local temp=$(tty)
|
|||
|
local GRAD1=${temp:5}
|
|||
|
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-$NO_COLOUR "
|
|||
|
}
|
|||
|
|
|||
|
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@gcsu202014)-(30/pts/6)-(0816/01-Aug-01)-- |
|
|||
|
|--($:~/tmp)-- |
|
|||
|
+---------------------------------------------------------------------------+
|
|||
|
|
|||
|
To help myself remember what colours are available, I wrote a script that
|
|||
|
output all the colours to the screen. Daniel Crisman has supplied a much
|
|||
|
nicer version which I include below:
|
|||
|
#!/bin/bash
|
|||
|
#
|
|||
|
# This file echoes a bunch of color codes to the
|
|||
|
# terminal to demonstrate what's available. Each
|
|||
|
# line is the color code of one forground color,
|
|||
|
# out of 17 (default + 16 escapes), followed by a
|
|||
|
# test use of that color on all nine background
|
|||
|
# colors (default + 8 escapes).
|
|||
|
#
|
|||
|
|
|||
|
T='gYw' # The test text
|
|||
|
|
|||
|
echo -e "\n 40m 41m 42m 43m\
|
|||
|
44m 45m 46m 47m";
|
|||
|
|
|||
|
for FGs in ' m' ' 1m' ' 30m' '1;30m' ' 31m' '1;31m' ' 32m' \
|
|||
|
'1;32m' ' 33m' '1;33m' ' 34m' '1;34m' ' 35m' '1;35m' \
|
|||
|
' 36m' '1;36m' ' 37m' '1;37m';
|
|||
|
do FG=${FGs// /}
|
|||
|
echo -en " $FGs \033[$FG $T "
|
|||
|
for BG in 40m 41m 42m 43m 44m 45m 46m 47m;
|
|||
|
do echo -en "$EINS \033[$FG\033[$BG $T \033[0m";
|
|||
|
done
|
|||
|
echo;
|
|||
|
done
|
|||
|
echo
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
6.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 |
|
|||
|
| Or |
|
|||
|
| \033[<L>;<C>f |
|
|||
|
| 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 |
|
|||
|
| |
|
|||
|
|- Clear the screen, move to (0,0): |
|
|||
|
| \033[2J |
|
|||
|
|- Erase to end of line: |
|
|||
|
| \033[K |
|
|||
|
| |
|
|||
|
|- 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 them. 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 Section 12.9 for a more extensive use of these codes.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
6.3. Xterm Title Bar Manipulations
|
|||
|
|
|||
|
I'm not sure that these escape sequences strictly qualify as "ANSI Escape
|
|||
|
Sequences," but in practice their use is almost identical so I've included
|
|||
|
them in this chapter.
|
|||
|
|
|||
|
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 \]
|
|||
|
(as discussed in Section 3.4, 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 incorrectly 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.
|
|||
|
|
|||
|
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 particularly
|
|||
|
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.
|
|||
|
|
|||
|
A suggestion from Charles Lepple (<clepple at negativezero dot org>) on
|
|||
|
setting the window title of the Xterm and the title of the corresponding icon
|
|||
|
separately. He uses this under WindowMaker because the title that's
|
|||
|
appropriate for an Xterm is usually too long for a 64x64 icon. "\[\e]1;
|
|||
|
icon-title\007\e]2;main-title\007\]". He says to set this in the prompt
|
|||
|
command because "I tried putting the string in PS1, but it causes flickering
|
|||
|
under some window managers because it results in setting the prompt multiple
|
|||
|
times when you are editing a multi-line command (at least under bash 1.4.x --
|
|||
|
and I was too lazy to fully explore the reasons behind it)." I had no trouble
|
|||
|
with it in the PS1 string, but didn't use any multi-line commands. He also
|
|||
|
points out that it works under xterm, xwsh, and dtterm, but not
|
|||
|
gnome-terminal (which uses only the main title). I also found it to work with
|
|||
|
rxvt, but not kterm.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
6.4. Xterm Title Bars and Screen
|
|||
|
|
|||
|
Non-screen users should skip this section. Of course, screen is an awesome
|
|||
|
program and what you should really do is rush out and find out what screen is
|
|||
|
- if you've read this far in the HOWTO, you're enough of a Command Line
|
|||
|
Interface Junkie that you need to know.
|
|||
|
|
|||
|
If you use screen in Xterms and you want to manipulate the title bar, your
|
|||
|
life may just have become a bit more complicated ... Screen can, but doesn't
|
|||
|
automatically, treat the Xterm title bar as a hardstatus line (whatever that
|
|||
|
means, but it's where we put our Xterm title). If you're a RedHat user,
|
|||
|
you'll probably find the following line in your ~/.screenrc:
|
|||
|
+---------------------------------------------------------------------------+
|
|||
|
| termcapinfo xterm 'hs:ts=\E]2;:fs=\007:ds=\E]2;screen\007' |
|
|||
|
+---------------------------------------------------------------------------+
|
|||
|
|
|||
|
If that line isn't in there, you should put it in. This allows the titlebar
|
|||
|
manipulations in the previous section to work under Xterm. But I found they
|
|||
|
failed when I used rxvt. I e-mailed a question about this to the screen
|
|||
|
maintainers, and Michael Schroeder (one of those good people labouring behind
|
|||
|
the scenes to make free Unix/Linux software as great as it is) told me to add
|
|||
|
the following to my ~/.screenrc:
|
|||
|
+---------------------------------------------------------------------------+
|
|||
|
| termcapinfo rxvt 'hs:ts=\E]2;:fs=\007:ds=\E]2;screen\007' |
|
|||
|
+---------------------------------------------------------------------------+
|
|||
|
|
|||
|
I don't know if this will work for other Xterm variants, but since the two
|
|||
|
lines are functionally identical except for the name of the Xterm type,
|
|||
|
perhaps ... I leave this as an exercise for the reader. It did fix my
|
|||
|
problem, although I haven't researched further to see if it interferes with
|
|||
|
the icon-titlebar naming distinction.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
6.5. Colours and Cursor Movement 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, get back information about the status of the terminal, or set
|
|||
|
colours. man tput doesn't go into much detail about the available commands,
|
|||
|
but Emilio Lopes e-mailed me to point out that man terminfo will give you a
|
|||
|
huge list of capabilities, many of which are device independent, and
|
|||
|
therefore better than the escape sequences previously mentioned. He suggested
|
|||
|
that I rewrite all the examples using tput for this reason. He is correct
|
|||
|
that I should, but I've had some trouble controlling it and getting it to do
|
|||
|
everything I want it to. However, I did rewrite one prompt which you can see
|
|||
|
as an example: Section 12.8.
|
|||
|
|
|||
|
Here is a list of tput capabilities that I have found useful:
|
|||
|
|
|||
|
tput Colour Capabilities
|
|||
|
|
|||
|
tput setab [1-7]
|
|||
|
Set a background colour using ANSI escape
|
|||
|
|
|||
|
tput setb [1-7]
|
|||
|
Set a background colour
|
|||
|
|
|||
|
tput setaf [1-7]
|
|||
|
Set a foreground colour using ANSI escape
|
|||
|
|
|||
|
tput setf [1-7]
|
|||
|
Set a foreground colour
|
|||
|
|
|||
|
|
|||
|
tput Text Mode Capabilities
|
|||
|
|
|||
|
tput bold
|
|||
|
Set bold mode
|
|||
|
|
|||
|
tput dim
|
|||
|
turn on half-bright mode
|
|||
|
|
|||
|
tput smul
|
|||
|
begin underline mode
|
|||
|
|
|||
|
tput rmul
|
|||
|
exit underline mode
|
|||
|
|
|||
|
tput rev
|
|||
|
Turn on reverse mode
|
|||
|
|
|||
|
tput smso
|
|||
|
Enter standout mode (bold on rxvt)
|
|||
|
|
|||
|
tput rmso
|
|||
|
Exit standout mode
|
|||
|
|
|||
|
tput sgr0
|
|||
|
Turn off all attributes (doesn't work quite as expected)
|
|||
|
|
|||
|
|
|||
|
tput Cursor Movement Capabilities
|
|||
|
|
|||
|
tput cup Y X
|
|||
|
Move cursor to screen location X,Y (top left is 0,0)
|
|||
|
|
|||
|
tput sc
|
|||
|
Save the cursor position
|
|||
|
|
|||
|
tput rc
|
|||
|
Restore the cursor position
|
|||
|
|
|||
|
tput lines
|
|||
|
Output the number of lines of the terminal
|
|||
|
|
|||
|
tput cols
|
|||
|
Output the number of columns of the terminal
|
|||
|
|
|||
|
tput cub N
|
|||
|
Move N characters left
|
|||
|
|
|||
|
tput cuf N
|
|||
|
Move N characters right
|
|||
|
|
|||
|
tput cub1
|
|||
|
move left one space
|
|||
|
|
|||
|
tput cuf1
|
|||
|
non-destructive space (move right one space)
|
|||
|
|
|||
|
tput ll
|
|||
|
last line, first column (if no cup)
|
|||
|
|
|||
|
tput cuu1
|
|||
|
up one line
|
|||
|
|
|||
|
|
|||
|
tput Clear and Insert Capabilities
|
|||
|
|
|||
|
tput ech N
|
|||
|
Erase N characters
|
|||
|
|
|||
|
tput clear
|
|||
|
clear screen and home cursor
|
|||
|
|
|||
|
tput el1
|
|||
|
Clear to beginning of line
|
|||
|
|
|||
|
tput el
|
|||
|
clear to end of line
|
|||
|
|
|||
|
tput ed
|
|||
|
clear to end of screen
|
|||
|
|
|||
|
tput ich N
|
|||
|
insert N characters (moves rest of line forward!)
|
|||
|
|
|||
|
tput il N
|
|||
|
insert N lines
|
|||
|
|
|||
|
|
|||
|
This is by no means a complete list of what terminfo and tput allow, in fact
|
|||
|
it's only the beginning. man tput and man terminfo if you want to know more.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
Chapter 7. 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 utilize 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 that are used heavily by the Bashprompt
|
|||
|
project are between octal 260 and 337 in the VGA fonts.
|
|||
|
#!/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.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
Chapter 8. The Bash Prompt Package
|
|||
|
|
|||
|
8.1. Availability
|
|||
|
|
|||
|
The Bash Prompt package was available at [http://bash.current.nu/] http://
|
|||
|
bash.current.nu/, and is the work of several people, co-ordinated by Rob
|
|||
|
Current (aka BadLandZ). The site was down in July 2001, but Rob Current
|
|||
|
assures me it will be back up soon. The package is in 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). Little work has been done on this
|
|||
|
project recently: I hope there's some more progress.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
8.2. Xterm Fonts
|
|||
|
|
|||
|
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 "VGA Fonts," which support different character sets than
|
|||
|
regular Xterm fonts. 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. I asked for an
|
|||
|
explanation of this difference, and S<>rgio Vale e Pace (space@gold.com.br)
|
|||
|
wrote me:
|
|||
|
|
|||
|
|
|||
|
I love computer history so here goes:
|
|||
|
|
|||
|
When IBM designed the first PC they needed some character codes to use,
|
|||
|
so they got the ASCII character table (128 numbers, letters, and some
|
|||
|
punctuation) and to fill a byte addressed table they added 128 more
|
|||
|
characters. Since the PC was designed to be a home computer, they fill
|
|||
|
the remaining 128 characters with dots, lines, points, etc, to be able to
|
|||
|
do borders, and grayscale effects (remember that we are talking about 2
|
|||
|
color graphics).
|
|||
|
|
|||
|
Time passes, PCs become a standard, IBM creates more powerful systems and
|
|||
|
the VGA standard is born, along with 256 colour graphics, and IBM
|
|||
|
continues to include their IBM-ASCII characters table.
|
|||
|
|
|||
|
More time passes, IBM has lost their leadership in the PC market, and the
|
|||
|
OS authors dicover that there are other languages in the world that use
|
|||
|
non-english characters, so they add international alphabet support in
|
|||
|
their systems. Since we now have bright and colorful screens, we can
|
|||
|
trash the dots, lines, etc. and use their space for accented characters
|
|||
|
and some greek letters, which you'll see in Linux.
|
|||
|
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
8.3. Changing the Xterm Font
|
|||
|
|
|||
|
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 through 7.1, it may be different on
|
|||
|
other distributions). cd to that directory, and run mkfontdir. Then run xset
|
|||
|
fp rehash and/or restart your X font server, whichever applies to your
|
|||
|
situation. 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] http://home.earthlink.net/
|
|||
|
~us5zahns/enl/ansifont.html (which I have borrowed from extensively while
|
|||
|
writing this).
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
8.4. Line Draw Characters without VGA Fonts
|
|||
|
|
|||
|
Xterm and rxvt can be switched into line-draw mode on the fly with the
|
|||
|
appropriate escape sequence. You'll need to switch back after you've output
|
|||
|
the characters you wanted or any text following it will be garbled. Prompts
|
|||
|
based on these output codes don't work on the console, instead producing the
|
|||
|
text equivalents.
|
|||
|
|
|||
|
To start a sequence of line draw characters, use an echo -e and the \033(0
|
|||
|
escape sequence. Most of the characters worth using are in the range lower
|
|||
|
case "a" through "z". Terminate the string with another escape sequence, \033
|
|||
|
(B .
|
|||
|
|
|||
|
The best method I've found for testing this is shown in the image below: use
|
|||
|
the escgen script mentioned earlier in the HOWTO to show the 100 to 200 octal
|
|||
|
range, echo the first escape sequence, run the escgen script for the same
|
|||
|
range, and echo the closing escape sequence. The image also shows how to use
|
|||
|
this in a prompt.
|
|||
|
|
|||
|
[rxvt-line-draw]
|
|||
|
|
|||
|
Using escape sequences in RXVT (also works in Xterm and RXVT derivatives like
|
|||
|
aterm, which is used here) to produce line draw characters. The "escgen"
|
|||
|
script used above is given earlier in the HOWTO.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
Chapter 9. Loading a Different Prompt
|
|||
|
|
|||
|
9.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 Section 2.6 for Johan Kullstam's note regarding the importance of
|
|||
|
putting the PS? strings in ~/.bashrc .
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
9.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.3. Loading Different Prompts in Different X Terms
|
|||
|
|
|||
|
If you have a specific prompt to go with a particular project, or some reason
|
|||
|
to load different prompts at different times, you can use multiple bashrc
|
|||
|
files instead of always using your ~/.bashrc file. The Bash command is
|
|||
|
something like bash --rcfile /home/giles/.bashprompt/bashrc/bashrcdan, which
|
|||
|
will start a new version of Bash in your current terminal. To use this in
|
|||
|
combination with a Window Manager menuing system, use a command like rxvt -e
|
|||
|
bash --rcfile /home/giles/.bashprompt/bashrc/bashrcdan. The exact command you
|
|||
|
use will be dependent on the syntax of your X term of choice and the location
|
|||
|
of the bashrc file you're using.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
Chapter 10. Loading Prompt Colours Dynamically
|
|||
|
|
|||
|
10.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[0m\]:\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.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
Chapter 11. Prompt Code Snippets
|
|||
|
|
|||
|
This section shows how to put various pieces of information into the Bash
|
|||
|
prompt. There are an infinite number of things that could be put in your
|
|||
|
prompt. Feel free to send me examples, I'll try to include what I think will
|
|||
|
be most widely used. If you have an alternate way to retrieve a piece of
|
|||
|
information here, and feel your method is more efficient, please contact me.
|
|||
|
It's easy to write bad code, I do it often, but it's great to write elegant
|
|||
|
code, and a pleasure to read it. I manage it every once in a while, and would
|
|||
|
love to have more of it to put in here.
|
|||
|
|
|||
|
To incorporate shell code in prompts, it has to be escaped. Usually, this
|
|||
|
will mean putting it inside \$(<command>) so that the output of command is
|
|||
|
substituted each time the prompt is generated.
|
|||
|
|
|||
|
Please keep in mind that I develop and test this code on a single user 900
|
|||
|
MHz Athlon with 256 meg of RAM, so the delay generated by these code snippets
|
|||
|
doesn't usually mean much to me. To help with this, I recently assembled a 25
|
|||
|
MHz 486 SX with 16 meg of RAM, and you will see the output of the "time"
|
|||
|
command for each snippet to indicate how much of a delay it causes on a
|
|||
|
slower machine.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
11.1. Built-in Escape Sequences
|
|||
|
|
|||
|
See Section 2.5 for a complete list of built-in escape sequences. This list
|
|||
|
is taken directly from the Bash man page, so you can also look there.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
11.2. Date and Time
|
|||
|
|
|||
|
If you don't like the built-ins for date and time, extracting the same
|
|||
|
information from the date command is relatively easy. Examples already seen
|
|||
|
in this HOWTO include date +%H%M, which will put in the hour in 24 hour
|
|||
|
format, and the minute. date "+%A, %d %B %Y" will give something like
|
|||
|
"Sunday, 06 June 1999". For a full list of the interpreted sequences, type
|
|||
|
date --help or man date.
|
|||
|
|
|||
|
Relative speed: "date ..." takes about 0.12 seconds on an unloaded 486SX25.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
11.3. Counting Files in the Current Directory
|
|||
|
|
|||
|
To determine how many files there are in the current directory, put in ls -1
|
|||
|
| wc -l. This uses wc to do a count of the number of lines (-l) in the output
|
|||
|
of ls -1. It doesn't count dotfiles. Please note that ls -l (that's an "L"
|
|||
|
rather than a "1" as in the previous examples) which I used in previous
|
|||
|
versions of this HOWTO will actually give you a file count one greater than
|
|||
|
the actual count. Thanks to Kam Nejad for this point.
|
|||
|
|
|||
|
If you want to count only files and NOT include symbolic links (just an
|
|||
|
example of what else you could do), you could use ls -l | grep -v ^l | wc -l
|
|||
|
(that's an "L" not a "1" this time, we want a "long" listing here). grep
|
|||
|
checks for any line beginning with "l" (indicating a link), and discards that
|
|||
|
line (-v).
|
|||
|
|
|||
|
Relative speed: "ls -1 /usr/bin/ | wc -l" takes about 1.03 seconds on an
|
|||
|
unloaded 486SX25 (/usr/bin/ on this machine has 355 files). "ls -l /usr/bin/
|
|||
|
| grep -v ^l | wc -l" takes about 1.19 seconds.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
11.4. Total Bytes in the Current Directory
|
|||
|
|
|||
|
If you want to know how much space the contents of the current directory take
|
|||
|
up, you can use something like the following:
|
|||
|
let TotalBytes=0
|
|||
|
|
|||
|
for Bytes in $(ls -l | grep "^-" | awk '{ print $5 }')
|
|||
|
do
|
|||
|
let TotalBytes=$TotalBytes+$Bytes
|
|||
|
done
|
|||
|
|
|||
|
# The if...fi's give a more specific output in byte, kilobyte, megabyte,
|
|||
|
# and gigabyte
|
|||
|
|
|||
|
if [ $TotalBytes -lt 1024 ]; then
|
|||
|
TotalSize=$(echo -e "scale=3 \n$TotalBytes \nquit" | bc)
|
|||
|
suffix="b"
|
|||
|
elif [ $TotalBytes -lt 1048576 ]; then
|
|||
|
TotalSize=$(echo -e "scale=3 \n$TotalBytes/1024 \nquit" | bc)
|
|||
|
suffix="kb"
|
|||
|
elif [ $TotalBytes -lt 1073741824 ]; then
|
|||
|
TotalSize=$(echo -e "scale=3 \n$TotalBytes/1048576 \nquit" | bc)
|
|||
|
suffix="Mb"
|
|||
|
else
|
|||
|
TotalSize=$(echo -e "scale=3 \n$TotalBytes/1073741824 \nquit" | bc)
|
|||
|
suffix="Gb"
|
|||
|
fi
|
|||
|
|
|||
|
echo -n "${TotalSize}${suffix}"
|
|||
|
|
|||
|
Code courtesy of me, Sam Schmit (<id at pt dot lu>), and Sam's uncle
|
|||
|
Jean-Paul, who ironed out a fairly major bug in my original code, and just
|
|||
|
generally cleaned it up.
|
|||
|
|
|||
|
Note that you could also just use ls -l | grep ^total | awk '{ print $2 }'
|
|||
|
because ls -l prints out a line at the beginning that is the approximate size
|
|||
|
of the directory in kilobytes - although for reasons unknown to me, it seems
|
|||
|
to be less accurate (but obviously faster) than the above script.
|
|||
|
|
|||
|
Relative speed: this process takes between 3.2 and 5.8 seconds in /usr/bin/
|
|||
|
(14.7 meg in the directory) on an unloaded 486SX25, depending on how much of
|
|||
|
the information is cached (if you use this in a prompt, more or less of it
|
|||
|
will be cached depending how long you work in the directory).
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
11.5. Checking the Current TTY
|
|||
|
|
|||
|
The tty command returns the filename of the terminal connected to standard
|
|||
|
input. This comes in two formats on the Linux systems I have used, either "/
|
|||
|
dev/tty4" or "/dev/pts/2". I've used several methods over time, but the
|
|||
|
simplest I've found so far (probably both Linux- and Bash-2.x specific) is
|
|||
|
temp=$(tty) ; echo ${temp:5}. This removes the first five characters of the
|
|||
|
tty output, in this case "/dev/".
|
|||
|
|
|||
|
Previously, I used tty | sed -e "s:/dev/::", which removes the leading "/dev/
|
|||
|
". Older systems (in my experience, RedHat through 5.2) returned only
|
|||
|
filenames in the "/dev/tty4" format, so I used tty | sed -e "s/.*tty\(.*\)/\1
|
|||
|
/".
|
|||
|
|
|||
|
An alternative method: ps ax | grep $$ | awk '{ print $2 }'.
|
|||
|
|
|||
|
Relative speed: the ${temp:5} method takes about 0.12 seconds on an unloaded
|
|||
|
486SX25, the sed-driven method takes about 0.19 seconds, the awk-driven
|
|||
|
method takes about 0.79 seconds.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
11.6. Stopped Jobs Count
|
|||
|
|
|||
|
Torben Fjerdingstad (<tfj at fjerdingstad dot dk>) wrote to tell me that he
|
|||
|
often stops jobs and then forgets about them. He uses his prompt to remind
|
|||
|
himself of stopped jobs. Apparently this is fairly popular, because as of
|
|||
|
Bash 2.04, there is a standard escape sequence for jobs managed by the shell:
|
|||
|
+---------------------------------------------------------------------------+
|
|||
|
|[giles@zinfandel]$ export PS1='\W[\j]\$ ' |
|
|||
|
|giles[0]$ man ls & |
|
|||
|
|[1] 31899 |
|
|||
|
|giles[1]$ xman & |
|
|||
|
|[2] 31907 |
|
|||
|
| |
|
|||
|
|[1]+ Stopped man ls |
|
|||
|
|giles[2]$ jobs |
|
|||
|
|[1]+ Stopped man ls |
|
|||
|
|[2]- Running xman & |
|
|||
|
|giles[2]$ |
|
|||
|
+---------------------------------------------------------------------------+
|
|||
|
|
|||
|
Note that this shows both stopped and running jobs. At the console, you
|
|||
|
probably want the complete count, but in an xterm you're probably only
|
|||
|
interested in the ones that are stopped. To display only these, you could use
|
|||
|
something like the following:
|
|||
|
+---------------------------------------------------------------------------+
|
|||
|
|[giles@zinfandel]$ function stoppedjobs { |
|
|||
|
|-- jobs -s | wc -l | sed -e "s/ //g" |
|
|||
|
|-- } |
|
|||
|
|[giles@zinfandel]$ export PS1='\W[`stoppedjobs`]\$ ' |
|
|||
|
|giles[0]$ jobs |
|
|||
|
|giles[0]$ man ls & |
|
|||
|
|[1] 32212 |
|
|||
|
| |
|
|||
|
|[1]+ Stopped man ls |
|
|||
|
|giles[0]$ man X & |
|
|||
|
|[2] 32225 |
|
|||
|
| |
|
|||
|
|[2]+ Stopped man X |
|
|||
|
|giles[2]$ jobs |
|
|||
|
|[1]- Stopped man ls |
|
|||
|
|[2]+ Stopped man X |
|
|||
|
|giles[2]$ xman & |
|
|||
|
|[3] 32246 |
|
|||
|
|giles[2]$ sleep 300 & |
|
|||
|
|[4] 32255 |
|
|||
|
|giles[2]$ jobs |
|
|||
|
|[1]- Stopped man ls |
|
|||
|
|[2]+ Stopped man X |
|
|||
|
|[3] Running xman & |
|
|||
|
|[4] Running sleep 300 & |
|
|||
|
+---------------------------------------------------------------------------+
|
|||
|
|
|||
|
This doesn't always show the stopped job in the prompt that follows
|
|||
|
immediately after the command is executed - it probably depends on whether
|
|||
|
the job is launched and put in the background before jobs is run.
|
|||
|
|
|||
|
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 stopped. This problem is fixed in 2.03.
|
|||
|
|
|||
|
Relative speed: 'jobs -s | wc -l | sed -e "s/ //g" ' takes about 0.24 seconds
|
|||
|
on an unloaded 486SX25.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
11.7. Load
|
|||
|
|
|||
|
The output of uptime can be used to determine both the system load and
|
|||
|
uptime, but its output is exceptionally difficult to parse. On a Linux
|
|||
|
system, this is made much easier to deal with by the existence of the /proc/
|
|||
|
file system. cat /proc/loadavg will show you the one minute, five minute, and
|
|||
|
fifteen minute load average, as well as a couple other numbers I don't know
|
|||
|
the meaning of (anyone care to fill me in?).
|
|||
|
|
|||
|
Getting the load from /proc/loadavg is easy (thanks to Jerry Peek for
|
|||
|
reminding me of this simple method): read one five fifteen rest < /proc/
|
|||
|
loadavg. Just print the value you want.
|
|||
|
|
|||
|
For those without the /proc/ filesystem, you can use uptime | sed -e "s/.*
|
|||
|
load average: \(.*\...\), \(.*\...\), \(.*\...\)/\1/" -e "s/ //g" and replace
|
|||
|
"\1" with "\2" or "\3" depending if you want the one minute, five minute, or
|
|||
|
fifteen minute load average. This is a remarkably ugly regular expression:
|
|||
|
send suggestions if you have a better one.
|
|||
|
|
|||
|
Relative speed: 'uptime | sed -e "s/.*load average: \(.*\...\), \(.*\...\), \
|
|||
|
(.*\...\)/\1/" -e "s/ //g" ' takes about 0.21 seconds on an unloaded 486SX25.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
11.8. Uptime
|
|||
|
|
|||
|
As with load, the data available through uptime is very difficult to parse.
|
|||
|
Again, if you have the /proc/ filesystem, take advantage of it. I wrote the
|
|||
|
following code to output just the time the system has been up:
|
|||
|
+---------------------------------------------------------------------------+
|
|||
|
|#!/bin/bash |
|
|||
|
|# |
|
|||
|
|# upt - show just the system uptime, days, hours, and minutes |
|
|||
|
| |
|
|||
|
|let upSeconds="$(cat /proc/uptime) && echo ${temp%%.*})" |
|
|||
|
|let secs=$((${upSeconds}%60)) |
|
|||
|
|let mins=$((${upSeconds}/60%60)) |
|
|||
|
|let hours=$((${upSeconds}/3600%24)) |
|
|||
|
|let days=$((${upSeconds}/86400)) |
|
|||
|
|if [ "${days}" -ne "0" ] |
|
|||
|
|then |
|
|||
|
| echo -n "${days}d" |
|
|||
|
|fi |
|
|||
|
|echo -n "${hours}h${mins}m" |
|
|||
|
+---------------------------------------------------------------------------+
|
|||
|
|
|||
|
Output looks like "1h31m" if the system has been up less than a day, or
|
|||
|
"14d17h3m" if it has been up more than a day. You can massage the output to
|
|||
|
look the way you want it to. This evolved after an e-mail discussion with
|
|||
|
David Osolkowski, who gave me some ideas.
|
|||
|
|
|||
|
Before I wrote that script, I had a couple emails with David O, who said "me
|
|||
|
and a couple guys got on irc and started hacking with sed and got this:
|
|||
|
uptime | sed -e 's/.* \(.* days,\)\? \(.*:..,\) .*/\1 \2/' -e's/,//g' -e 's/
|
|||
|
days/d/' -e 's/ up //'. It's ugly, and doesn't use regex nearly as well as it
|
|||
|
should, but it works. It's pretty slow on a P75, though, so I removed it."
|
|||
|
Considering how much uptime output varies depending on how long a system has
|
|||
|
been up, I was impressed they managed as well as they did. You can use this
|
|||
|
on systems without /proc/ filesystem, but as he says, it may be slow.
|
|||
|
|
|||
|
Relative speed: the "upt" script takes about 0.68 seconds on an unloaded
|
|||
|
486SX25 (half that as a function). Contrary to David's guess, his use of sed
|
|||
|
to parse the output of "uptime" takes only 0.22 seconds.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
11.9. Number of Processes
|
|||
|
|
|||
|
ps ax | wc -l | tr -d " " OR ps ax | wc -l | awk '{print $1}' OR ps ax | wc
|
|||
|
-l | sed -e "s: ::g". In each case, tr or awk or sed is used to remove the
|
|||
|
undesirable whitespace.
|
|||
|
|
|||
|
Relative speed: any one of these variants takes about 0.9 seconds on an
|
|||
|
unloaded 486SX25.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
11.10. Controlling the Size and Appearance of $PWD
|
|||
|
|
|||
|
Unix allows long file names, which can lead to the value of $PWD being very
|
|||
|
long. Some people (notably the default RedHat prompt) choose to use the
|
|||
|
basename of the current working directory (ie. "giles" if $PWD="/home/
|
|||
|
giles"). I like more info than that, but it's often desirable to limit the
|
|||
|
length of the directory name, and it makes the most sense to truncate on the
|
|||
|
left.
|
|||
|
# How many characters of the $PWD should be kept
|
|||
|
local pwdmaxlen=30
|
|||
|
# Indicator that there has been directory truncation:
|
|||
|
#trunc_symbol="<"
|
|||
|
local trunc_symbol="..."
|
|||
|
if [ ${#PWD} -gt $pwdmaxlen ]
|
|||
|
then
|
|||
|
local pwdoffset=$(( ${#PWD} - $pwdmaxlen ))
|
|||
|
newPWD="${trunc_symbol}${PWD:$pwdoffset:$pwdmaxlen}"
|
|||
|
else
|
|||
|
newPWD=${PWD}
|
|||
|
fi
|
|||
|
|
|||
|
The above code can be executed as part of PROMPT_COMMAND, and the environment
|
|||
|
variable generated (newPWD) can then be included in the prompt. Thanks to
|
|||
|
Alexander Mikhailian <mikhailian at altern dot org> who rewrote the code to
|
|||
|
utilize new Bash functionality, thus speeding it up considerably.
|
|||
|
|
|||
|
Risto Juola (risto AT risto.net) wrote to say that he preferred to have the
|
|||
|
"~" in the $newPWD, so he wrote another version:
|
|||
|
pwd_length=20
|
|||
|
|
|||
|
DIR=`pwd`
|
|||
|
|
|||
|
echo $DIR | grep "^$HOME" >> /dev/null
|
|||
|
|
|||
|
if [ $? -eq 0 ]
|
|||
|
then
|
|||
|
CURRDIR=`echo $DIR | awk -F$HOME '{print $2}'`
|
|||
|
newPWD="~$CURRDIR"
|
|||
|
|
|||
|
if [ $(echo -n $newPWD | wc -c | tr -d " ") -gt $pwd_length ]
|
|||
|
then
|
|||
|
newPWD="~/..$(echo -n $PWD | sed -e "s/.*\(.\{$pwd_length\}\)/\1/")"
|
|||
|
fi
|
|||
|
elif [ "$DIR" = "$HOME" ]
|
|||
|
then
|
|||
|
newPWD="~"
|
|||
|
elif [ $(echo -n $PWD | wc -c | tr -d " ") -gt $pwd_length ]
|
|||
|
then
|
|||
|
newPWD="..$(echo -n $PWD | sed -e "s/.*\(.\{$pwd_length\}\)/\1/")"
|
|||
|
else
|
|||
|
newPWD="$(echo -n $PWD)"
|
|||
|
fi
|
|||
|
|
|||
|
Relative speed: the first version takes about 0.45 seconds on an unloaded
|
|||
|
486SX25. Risto's version takes about 0.80 to 0.95 seconds. The variation in
|
|||
|
this case is due to whether or not truncation is required.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
11.11. Laptop Power
|
|||
|
|
|||
|
If you have a laptop with APM installed, try the following PROMPT_COMMAND to
|
|||
|
create an environment variable ${battery} you can add to your prompt. This
|
|||
|
will indicate if AC power is connected and percentage power remaining. AC
|
|||
|
power is indicated by a "^" (for on) and a "v" (for off) before the
|
|||
|
percentage value.
|
|||
|
function prompt_command {
|
|||
|
# As much of the response of the "apm" command as is
|
|||
|
# necessary to identify the given condition:
|
|||
|
NO_AC_MESG="AC off"
|
|||
|
AC_MESG="AC on"
|
|||
|
|
|||
|
APMD_RESPONSE="$(apm)"
|
|||
|
case ${APMD_RESPONSE} in
|
|||
|
*${AC_MESG}*)
|
|||
|
ACstat="^"
|
|||
|
;;
|
|||
|
*${NO_AC_MESG}*)
|
|||
|
ACstat="v"
|
|||
|
;;
|
|||
|
esac
|
|||
|
|
|||
|
battery="${temp##* }"
|
|||
|
battery="${ACstat}${battery}"
|
|||
|
}
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
11.12. Having the Prompt Ignored on Cut and Paste
|
|||
|
|
|||
|
This one is weird but cool. Rory Toma <rory at corp dot webtv dot net> wrote
|
|||
|
to suggest a prompt like this: : rory@demon ; . How is this useful? You can
|
|||
|
triple click on any previous command (in Linux, anyway) to highlight the
|
|||
|
whole line, then paste that line in front of another prompt and the stuff
|
|||
|
between the ":" and the """ is ignored, like so:
|
|||
|
: rory@demon ; uptime
|
|||
|
5:15pm up 6 days, 23:04, 2 users, load average: 0.00, 0.00, 0.00
|
|||
|
: rory@demon ; : rory@demon ; uptime
|
|||
|
5:15pm up 6 days, 23:04, 2 users, load average: 0.00, 0.00, 0.00
|
|||
|
|
|||
|
The prompt is a no-op, and if your PS2 is set to a space, multiple lines can
|
|||
|
be cut and pasted as well.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
11.13. New Mail
|
|||
|
|
|||
|
Several people have sent me methods for checking whether or not they had new
|
|||
|
e-mail. Most of them relied on programs that aren't on every system. Then I
|
|||
|
received the following code from Henrik Veenpere: cat $MAIL |grep -c ^
|
|||
|
Message-. This is simple and elegant, and I like it.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
11.14. Prompt Beeps After Long-Running Commands
|
|||
|
|
|||
|
Robb Matzke (matzke at llnl dot gov) sent me this a long time ago (sorry
|
|||
|
Robb, should have put it in sooner!). This prompt uses Perl and the builtin
|
|||
|
times command to determine if the program that just finished running has used
|
|||
|
more than a certain amount of time. The assumption is that you might have
|
|||
|
changed desktops by then and notification would be nice, so it rings a bell.
|
|||
|
I've tried to avoid using Perl because the overhead is fairly high, but this
|
|||
|
is a good use for it.
|
|||
|
|
|||
|
I haven't tested this prompt myself. I like the idea though. Robb includes
|
|||
|
instructions in the comments.
|
|||
|
#!/usr/bin/perl
|
|||
|
require 5.003;
|
|||
|
use strict;
|
|||
|
|
|||
|
###############################################################################
|
|||
|
# prompt_bell -- execute arbitrary commands contingent upon CPU time
|
|||
|
#
|
|||
|
# Copyright (C) 2000 Robb Matzke
|
|||
|
#
|
|||
|
# This program is free software; you can redistribute it and/or modify it
|
|||
|
# under the terms of the GNU General Public License as published by the
|
|||
|
# Free Software Foundation; either version 2 of the License, or (at your
|
|||
|
# option) any later version.
|
|||
|
#
|
|||
|
# This program is distributed in the hope that it will be useful, but
|
|||
|
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
|||
|
# Public License for more details.
|
|||
|
#
|
|||
|
# You should have received a copy of the GNU General Public License along
|
|||
|
# with this program; see the file COPYING. If not, write to the Free
|
|||
|
# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|||
|
# 02111-1307, USA.
|
|||
|
#
|
|||
|
# Purpose:
|
|||
|
#
|
|||
|
# This program is intended to be called each time a shell prompt is
|
|||
|
# displayed. It looks at current CPU times (user+system) for the shell and
|
|||
|
# its children, and if the CPU time is more than some user-specified amount
|
|||
|
# then user-specified commands are executed. The author uses it to provide
|
|||
|
# an audio indication of when a long-running command completes.
|
|||
|
#
|
|||
|
# Usage:
|
|||
|
#
|
|||
|
# The prompt_bell command takes two arguments: the name of a file
|
|||
|
# containing the latest CPU usage information for the shell and its
|
|||
|
# children, and some optional state information from the environment
|
|||
|
# variable $PROMPT_BELL_STATE.
|
|||
|
#
|
|||
|
# The times file simply contains one or more times, zero or more to a line,
|
|||
|
# each of the form `#h#m#.#s' where `#' is a sequence of one or more
|
|||
|
# decimal digits and `#h' is the optional number of hours, `#m' is the
|
|||
|
# required number of minutes, and `#.#s' is the number of seconds and
|
|||
|
# fractions thereof. The total time is the sum of all the times in this
|
|||
|
# file. Example:
|
|||
|
#
|
|||
|
# 0m0.050s 0m0.060s
|
|||
|
# 0m15.790s 0m0.220s
|
|||
|
#
|
|||
|
# The output from this command is one or more semicolon-separated shell
|
|||
|
# commands which should be eval'd by the caller. If the difference between
|
|||
|
# the current CPU times and the previous CPU times (stored in environment
|
|||
|
# variable PROMPT_BELL_STATE) is more than $PROMPT_BELL_TIME seconds
|
|||
|
# (default 10) then the commands printed include the value of environment
|
|||
|
# variable PROMPT_BELL_CMD (default is "echo -ne '\a'").
|
|||
|
#
|
|||
|
# Typical usage is:
|
|||
|
# eval "`prompt_bell $TIMES_FILE $PROMPT_BELL_STATE`"
|
|||
|
#
|
|||
|
# and this command is usually part of the bash PROMPT_COMMAND. The author's
|
|||
|
# .bashrc contains the following:
|
|||
|
#
|
|||
|
# PROMPT_BELL_TIME=15
|
|||
|
# PROMPT_BELL_CMD="echo -e 'done.\a'"
|
|||
|
#
|
|||
|
# COMMAND_PROMPT='TIMES_FILE=/tmp/times.$$;
|
|||
|
# times >$TIMES_FILE;
|
|||
|
# eval "`prompt_bell $TIMES_FILE $PROMPT_BELL_STATE`";
|
|||
|
# /bin/rm -f $TIMES_FILE'
|
|||
|
# export PROMPT_BELL_TIME PROMPT_BELL_CMD COMMAND_PROMPT
|
|||
|
#
|
|||
|
# Note: the output of `times' is stored in a temporary file to prevent it
|
|||
|
# from being executed in a subshell whose CPU times are always nearly zero.
|
|||
|
#
|
|||
|
##############################################################################
|
|||
|
|
|||
|
# Convert #h#m#s to seconds.
|
|||
|
sub seconds {
|
|||
|
my($hms) = @_;
|
|||
|
my($h,$m,$s) = $hms =~ /^(?:(\d+)h)?(\d+)m(\d+\.\d+)s/;
|
|||
|
return $h*3600 + $m*60 + $s;
|
|||
|
}
|
|||
|
|
|||
|
# Obtain processor times in seconds
|
|||
|
my $times_file = shift;
|
|||
|
my $ptime_cur = 0;
|
|||
|
open TIMES_FILE, $times_file or die "prompt_bell: $times_file: $!\n";
|
|||
|
while (<TIMES_FILE>) {
|
|||
|
s/(?:(\d+)h)?(\d+)m(\d+(?:\.\d+)?)s/$ptime_cur+=$1*3600+$2*60+$3/eg;
|
|||
|
}
|
|||
|
close TIMES_FILE;
|
|||
|
|
|||
|
|
|||
|
# Obtain previous state to compute deltas.
|
|||
|
my $ptime_prev = shift;
|
|||
|
|
|||
|
# If the processor time was more than $PROMPT_BELL_TIME or 10 seconds
|
|||
|
# then beep.
|
|||
|
my $beep;
|
|||
|
my $limit = exists $ENV{PROMPT_BELL_TIME}?$ENV{PROMPT_BELL_TIME}:10;
|
|||
|
if ($ptime_cur-$ptime_prev>$limit) {
|
|||
|
$beep = ";" . ($ENV{PROMPT_BELL_CMD} || "echo -ne '\\a'");
|
|||
|
}
|
|||
|
|
|||
|
# Generate the shell commands
|
|||
|
print "PROMPT_BELL_STATE=$ptime_cur$beep\n";
|
|||
|
exit 0;
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
Chapter 12. Example Prompts
|
|||
|
|
|||
|
12.1. Examples on the Web
|
|||
|
|
|||
|
Over time, many people have e-mailed me excellent examples, and I've written
|
|||
|
some interesting ones myself. There are too many to include here, so I have
|
|||
|
put all of the examples together into some web pages which can be seen at
|
|||
|
[http://www.gilesorr.com/bashprompt/] http://www.gilesorr.com/bashprompt/.
|
|||
|
Most of the examples given here can also be seen on the web.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
12.2. 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*|rxvt*)
|
|||
|
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='+ '
|
|||
|
}
|
|||
|
|
|||
|
[proml]
|
|||
|
|
|||
|
The lightweight proml prompt, showing time, username, machine name, and
|
|||
|
working directory in colour. It also modifies the title of the terminal.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
12.3. Dan's Prompt
|
|||
|
|
|||
|
Dan was a coworker of mine at the university I work at for a while. Dan used
|
|||
|
csh and tcsh for a long time before moving to Bash, so he uses the history
|
|||
|
number a lot. He uses "screen" a lot, and for that, it's helpful to have the
|
|||
|
tty. The last part of his prompt is the return value of the last executed
|
|||
|
command. Dan doesn't like having the $PWD in his prompt because it makes the
|
|||
|
prompt grow and shrink too much.
|
|||
|
#!/bin/bash
|
|||
|
# Dan's prompt looks like this:
|
|||
|
# 543,p3,0$
|
|||
|
#
|
|||
|
PROMPT_COMMAND=""
|
|||
|
function dan {
|
|||
|
local cur_tty=$(temp=$(tty) ; echo ${temp:5});
|
|||
|
PS1="\!,$cur_tty,\$?\$ "
|
|||
|
}
|
|||
|
|
|||
|
[dan]
|
|||
|
|
|||
|
Dan's prompt: history number, tty number, return value of the last executed
|
|||
|
function.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
12.4. 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="> "
|
|||
|
}
|
|||
|
|
|||
|
[elite]
|
|||
|
|
|||
|
The elite prompt from the Bashprompt Themes.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
12.5. A "Power User" Prompt
|
|||
|
|
|||
|
I actually did use this prompt for a while, 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 ... A rewrite
|
|||
|
using newer Bash functionality might help, but 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 "^-" | awk '{print $5}')
|
|||
|
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='+ '
|
|||
|
}
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
12.6. Prompt Depending on Connection Type
|
|||
|
|
|||
|
Bradley M Alexander (storm@tux.org) had the excellent idea of reminding his
|
|||
|
users what kind of connection they were using to his machine(s), so he
|
|||
|
colour-codes prompts dependent on connection type. Here's the bashrc he
|
|||
|
supplied to me:
|
|||
|
# /etc/bashrc
|
|||
|
|
|||
|
# System wide functions and aliases
|
|||
|
# Environment stuff goes in /etc/profile
|
|||
|
|
|||
|
# For some unknown reason bash refuses to inherit
|
|||
|
# PS1 in some circumstances that I can't figure out.
|
|||
|
# Putting PS1 here ensures that it gets loaded every time.
|
|||
|
|
|||
|
# Set up prompts. Color code them for logins. Red for root, white for
|
|||
|
# user logins, green for ssh sessions, cyan for telnet,
|
|||
|
# magenta with red "(ssh)" for ssh + su, magenta for telnet.
|
|||
|
THIS_TTY=tty`ps aux | grep $$ | grep bash | awk '{ print $7 }'`
|
|||
|
SESS_SRC=`who | grep $THIS_TTY | awk '{ print $6 }'`
|
|||
|
|
|||
|
SSH_FLAG=0
|
|||
|
SSH_IP=`echo $SSH_CLIENT | awk '{ print $1 }'`
|
|||
|
if [ $SSH_IP ] ; then
|
|||
|
SSH_FLAG=1
|
|||
|
fi
|
|||
|
SSH2_IP=`echo $SSH2_CLIENT | awk '{ print $1 }'`
|
|||
|
if [ $SSH2_IP ] ; then
|
|||
|
SSH_FLAG=1
|
|||
|
fi
|
|||
|
if [ $SSH_FLAG -eq 1 ] ; then
|
|||
|
CONN=ssh
|
|||
|
elif [ -z $SESS_SRC ] ; then
|
|||
|
CONN=lcl
|
|||
|
elif [ $SESS_SRC = "(:0.0)" -o $SESS_SRC = "" ] ; then
|
|||
|
CONN=lcl
|
|||
|
else
|
|||
|
CONN=tel
|
|||
|
fi
|
|||
|
|
|||
|
# Okay...Now who we be?
|
|||
|
if [ `/usr/bin/whoami` = "root" ] ; then
|
|||
|
USR=priv
|
|||
|
else
|
|||
|
USR=nopriv
|
|||
|
fi
|
|||
|
|
|||
|
#Set some prompts...
|
|||
|
if [ $CONN = lcl -a $USR = nopriv ] ; then
|
|||
|
PS1="[\u \W]\\$ "
|
|||
|
elif [ $CONN = lcl -a $USR = priv ] ; then
|
|||
|
PS1="\[\033[01;31m\][\w]\\$\[\033[00m\] "
|
|||
|
elif [ $CONN = tel -a $USR = nopriv ] ; then
|
|||
|
PS1="\[\033[01;34m\][\u@\h \W]\\$\[\033[00m\] "
|
|||
|
elif [ $CONN = tel -a $USR = priv ] ; then
|
|||
|
PS1="\[\033[01;30;45m\][\u@\h \W]\\$\[\033[00m\] "
|
|||
|
elif [ $CONN = ssh -a $USR = nopriv ] ; then
|
|||
|
PS1="\[\033[01;32m\][\u@\h \W]\\$\[\033[00m\] "
|
|||
|
elif [ $CONN = ssh -a $USR = priv ] ; then
|
|||
|
PS1="\[\033[01;35m\][\u@\h \W]\\$\[\033[00m\] "
|
|||
|
fi
|
|||
|
|
|||
|
# PS1="[\u@\h \W]\\$ "
|
|||
|
export PS1
|
|||
|
alias which="type -path"
|
|||
|
alias dir="ls -lF --color"
|
|||
|
alias dirs="ls -lFS --color"
|
|||
|
alias h=history
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
12.7. 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 with tty number
|
|||
|
# by Giles - created 2 November 98, last tweaked 31 July 2001
|
|||
|
#
|
|||
|
# This is a variant on "termwide" that incorporates the tty number.
|
|||
|
#
|
|||
|
|
|||
|
hostnam=$(hostname -s)
|
|||
|
usernam=$(whoami)
|
|||
|
temp="$(tty)"
|
|||
|
# Chop off the first five chars of tty (ie /dev/):
|
|||
|
cur_tty="${temp:5}"
|
|||
|
unset temp
|
|||
|
|
|||
|
function prompt_command {
|
|||
|
|
|||
|
# Find the width of the prompt:
|
|||
|
TERMWIDTH=${COLUMNS}
|
|||
|
|
|||
|
# Add all the accessories below ...
|
|||
|
local temp="--(${usernam}@${hostnam}:${cur_tty})---(${PWD})--"
|
|||
|
|
|||
|
let fillsize=${TERMWIDTH}-${#temp}
|
|||
|
if [ "$fillsize" -gt "0" ]
|
|||
|
then
|
|||
|
fill="-------------------------------------------------------------------------------------------------------------------------------------------"
|
|||
|
# It's theoretically possible someone could need more
|
|||
|
# dashes than above, but very unlikely! HOWTO users,
|
|||
|
# the above should be ONE LINE, it may not cut and
|
|||
|
# paste properly
|
|||
|
fill="${fill:0:${fillsize}}"
|
|||
|
newPWD="${PWD}"
|
|||
|
fi
|
|||
|
|
|||
|
if [ "$fillsize" -lt "0" ]
|
|||
|
then
|
|||
|
fill=""
|
|||
|
let cut=3-${fillsize}
|
|||
|
newPWD="...${PWD:${cut}}"
|
|||
|
fi
|
|||
|
}
|
|||
|
|
|||
|
PROMPT_COMMAND=prompt_command
|
|||
|
|
|||
|
function twtty {
|
|||
|
|
|||
|
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*|rxvt*)
|
|||
|
TITLEBAR='\[\033]0;\u@\h:\w\007\]'
|
|||
|
;;
|
|||
|
*)
|
|||
|
TITLEBAR=""
|
|||
|
;;
|
|||
|
esac
|
|||
|
|
|||
|
PS1="$TITLEBAR\
|
|||
|
$YELLOW-$LIGHT_BLUE-(\
|
|||
|
$YELLOW\$usernam$LIGHT_BLUE@$YELLOW\$hostnam$LIGHT_BLUE:$WHITE\$cur_tty\
|
|||
|
${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 "
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
[twtty]
|
|||
|
|
|||
|
The twtty prompt in action.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
12.8. The Floating Clock Prompt
|
|||
|
|
|||
|
I've rewritten this prompt several times. It was originally written using
|
|||
|
octal escape sequences, but the ones I needed most for this (save and restore
|
|||
|
cursor position) aren't honoured by one of the commonest terminal emulators,
|
|||
|
rxvt. I rewrote it using tput, and that's what you see here. The required
|
|||
|
tput codes seem to be universally honoured. The body of the prompt is
|
|||
|
essentially the same as the "Lightweight" prompt shown earlier, but a clock
|
|||
|
is kept floating in the upper right corner of the term. It will reposition
|
|||
|
itself correctly even if the term is resized.
|
|||
|
#!/bin/bash
|
|||
|
|
|||
|
# Rewrite of "clock" using tput
|
|||
|
|
|||
|
function prompt_command {
|
|||
|
# prompt_x is where to position the cursor to write the clock
|
|||
|
let prompt_x=$(tput cols)-6
|
|||
|
# Move up one; not sure why we need to do this, but without this, I always
|
|||
|
# got an extra blank line between prompts
|
|||
|
tput cuu1
|
|||
|
tput sc
|
|||
|
tput cup 0 ${prompt_x}
|
|||
|
tput setaf 4 ; tput bold
|
|||
|
echo -n "["
|
|||
|
tput setaf 1
|
|||
|
echo -n "$(date +%H%M)"
|
|||
|
tput setaf 4 ; tput bold
|
|||
|
echo -n "]"
|
|||
|
tput rc
|
|||
|
}
|
|||
|
|
|||
|
PROMPT_COMMAND=prompt_command
|
|||
|
|
|||
|
function clockt {
|
|||
|
local BLUE="\[$(tput setaf 4 ; tput bold)\]"
|
|||
|
local LIGHT_RED="\[$(tput setaf 1 ; tput bold)\]"
|
|||
|
local WHITE="\[$(tput setaf 7 ; tput bold)\]"
|
|||
|
local NO_COLOUR="\[$(tput sgr0)\]"
|
|||
|
case $TERM in
|
|||
|
xterm*|rxvt*)
|
|||
|
TITLEBAR='\[\033]0;\u@\h:\w\007\]'
|
|||
|
;;
|
|||
|
*)
|
|||
|
TITLEBAR=""
|
|||
|
;;
|
|||
|
esac
|
|||
|
|
|||
|
PS1="${TITLEBAR}\
|
|||
|
$BLUE[$LIGHT_RED\u@\h:\w$BLUE]\
|
|||
|
$WHITE\$$NO_COLOUR "
|
|||
|
PS2='> '
|
|||
|
PS4='+ '
|
|||
|
}
|
|||
|
|
|||
|
[clockt]
|
|||
|
|
|||
|
The floating clock prompt in action. The clock will stay in correct position
|
|||
|
even if the term is resized.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
12.9. The Elegant Useless Clock Prompt
|
|||
|
|
|||
|
This is one of the more attractive (and useless) prompts I've made. 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}<7D>"
|
|||
|
# 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}
|
|||
|
newPWD="...$(echo -n $PWD | sed -e "s/\(^.\{$cutt\}\)\(.*\)/\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 "
|
|||
|
|
|||
|
}
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
Appendix A. GNU Free Documentation License
|
|||
|
|
|||
|
Version 1.1, March 2000
|
|||
|
|
|||
|
|
|||
|
Copyright (C) 2000 Free Software Foundation, Inc. 59 Temple Place, Suite
|
|||
|
330, Boston, MA 02111-1307 USA Everyone is permitted to copy and
|
|||
|
distribute verbatim copies of this license document, but changing it is
|
|||
|
not allowed.
|
|||
|
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
0. PREAMBLE
|
|||
|
|
|||
|
The purpose of this License is to make a manual, textbook, or other written
|
|||
|
document "free" in the sense of freedom: to assure everyone the effective
|
|||
|
freedom to copy and redistribute it, with or without modifying it, either
|
|||
|
commercially or noncommercially. Secondarily, this License preserves for the
|
|||
|
author and publisher a way to get credit for their work, while not being
|
|||
|
considered responsible for modifications made by others.
|
|||
|
|
|||
|
This License is a kind of "copyleft", which means that derivative works of
|
|||
|
the document must themselves be free in the same sense. It complements the
|
|||
|
GNU General Public License, which is a copyleft license designed for free
|
|||
|
software.
|
|||
|
|
|||
|
We have designed this License in order to use it for manuals for free
|
|||
|
software, because free software needs free documentation: a free program
|
|||
|
should come with manuals providing the same freedoms that the software does.
|
|||
|
But this License is not limited to software manuals; it can be used for any
|
|||
|
textual work, regardless of subject matter or whether it is published as a
|
|||
|
printed book. We recommend this License principally for works whose purpose
|
|||
|
is instruction or reference.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
1. APPLICABILITY AND DEFINITIONS
|
|||
|
|
|||
|
This License applies to any manual or other work that contains a notice
|
|||
|
placed by the copyright holder saying it can be distributed under the terms
|
|||
|
of this License. The "Document", below, refers to any such manual or work.
|
|||
|
Any member of the public is a licensee, and is addressed as "you".
|
|||
|
|
|||
|
A "Modified Version" of the Document means any work containing the Document
|
|||
|
or a portion of it, either copied verbatim, or with modifications and/or
|
|||
|
translated into another language.
|
|||
|
|
|||
|
A "Secondary Section" is a named appendix or a front-matter section of the
|
|||
|
Document that deals exclusively with the relationship of the publishers or
|
|||
|
authors of the Document to the Document's overall subject (or to related
|
|||
|
matters) and contains nothing that could fall directly within that overall
|
|||
|
subject. (For example, if the Document is in part a textbook of mathematics,
|
|||
|
a Secondary Section may not explain any mathematics.) The relationship could
|
|||
|
be a matter of historical connection with the subject or with related
|
|||
|
matters, or of legal, commercial, philosophical, ethical or political
|
|||
|
position regarding them.
|
|||
|
|
|||
|
The "Invariant Sections" are certain Secondary Sections whose titles are
|
|||
|
designated, as being those of Invariant Sections, in the notice that says
|
|||
|
that the Document is released under this License.
|
|||
|
|
|||
|
The "Cover Texts" are certain short passages of text that are listed, as
|
|||
|
Front-Cover Texts or Back-Cover Texts, in the notice that says that the
|
|||
|
Document is released under this License.
|
|||
|
|
|||
|
A "Transparent" copy of the Document means a machine-readable copy,
|
|||
|
represented in a format whose specification is available to the general
|
|||
|
public, whose contents can be viewed and edited directly and
|
|||
|
straightforwardly with generic text editors or (for images composed of
|
|||
|
pixels) generic paint programs or (for drawings) some widely available
|
|||
|
drawing editor, and that is suitable for input to text formatters or for
|
|||
|
automatic translation to a variety of formats suitable for input to text
|
|||
|
formatters. A copy made in an otherwise Transparent file format whose markup
|
|||
|
has been designed to thwart or discourage subsequent modification by readers
|
|||
|
is not Transparent. A copy that is not "Transparent" is called "Opaque".
|
|||
|
|
|||
|
Examples of suitable formats for Transparent copies include plain ASCII
|
|||
|
without markup, Texinfo input format, LaTeX input format, SGML or XML using a
|
|||
|
publicly available DTD, and standard-conforming simple HTML designed for
|
|||
|
human modification. Opaque formats include PostScript, PDF, proprietary
|
|||
|
formats that can be read and edited only by proprietary word processors, SGML
|
|||
|
or XML for which the DTD and/or processing tools are not generally available,
|
|||
|
and the machine-generated HTML produced by some word processors for output
|
|||
|
purposes only.
|
|||
|
|
|||
|
The "Title Page" means, for a printed book, the title page itself, plus such
|
|||
|
following pages as are needed to hold, legibly, the material this License
|
|||
|
requires to appear in the title page. For works in formats which do not have
|
|||
|
any title page as such, "Title Page" means the text near the most prominent
|
|||
|
appearance of the work's title, preceding the beginning of the body of the
|
|||
|
text.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
2. VERBATIM COPYING
|
|||
|
|
|||
|
You may copy and distribute the Document in any medium, either commercially
|
|||
|
or noncommercially, provided that this License, the copyright notices, and
|
|||
|
the license notice saying this License applies to the Document are reproduced
|
|||
|
in all copies, and that you add no other conditions whatsoever to those of
|
|||
|
this License. You may not use technical measures to obstruct or control the
|
|||
|
reading or further copying of the copies you make or distribute. However, you
|
|||
|
may accept compensation in exchange for copies. If you distribute a large
|
|||
|
enough number of copies you must also follow the conditions in section 3.
|
|||
|
|
|||
|
You may also lend copies, under the same conditions stated above, and you may
|
|||
|
publicly display copies.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
3. COPYING IN QUANTITY
|
|||
|
|
|||
|
If you publish printed copies of the Document numbering more than 100, and
|
|||
|
the Document's license notice requires Cover Texts, you must enclose the
|
|||
|
copies in covers that carry, clearly and legibly, all these Cover Texts:
|
|||
|
Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover.
|
|||
|
Both covers must also clearly and legibly identify you as the publisher of
|
|||
|
these copies. The front cover must present the full title with all words of
|
|||
|
the title equally prominent and visible. You may add other material on the
|
|||
|
covers in addition. Copying with changes limited to the covers, as long as
|
|||
|
they preserve the title of the Document and satisfy these conditions, can be
|
|||
|
treated as verbatim copying in other respects.
|
|||
|
|
|||
|
If the required texts for either cover are too voluminous to fit legibly, you
|
|||
|
should put the first ones listed (as many as fit reasonably) on the actual
|
|||
|
cover, and continue the rest onto adjacent pages.
|
|||
|
|
|||
|
If you publish or distribute Opaque copies of the Document numbering more
|
|||
|
than 100, you must either include a machine-readable Transparent copy along
|
|||
|
with each Opaque copy, or state in or with each Opaque copy a
|
|||
|
publicly-accessible computer-network location containing a complete
|
|||
|
Transparent copy of the Document, free of added material, which the general
|
|||
|
network-using public has access to download anonymously at no charge using
|
|||
|
public-standard network protocols. If you use the latter option, you must
|
|||
|
take reasonably prudent steps, when you begin distribution of Opaque copies
|
|||
|
in quantity, to ensure that this Transparent copy will remain thus accessible
|
|||
|
at the stated location until at least one year after the last time you
|
|||
|
distribute an Opaque copy (directly or through your agents or retailers) of
|
|||
|
that edition to the public.
|
|||
|
|
|||
|
It is requested, but not required, that you contact the authors of the
|
|||
|
Document well before redistributing any large number of copies, to give them
|
|||
|
a chance to provide you with an updated version of the Document.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
4. MODIFICATIONS
|
|||
|
|
|||
|
You may copy and distribute a Modified Version of the Document under the
|
|||
|
conditions of sections 2 and 3 above, provided that you release the Modified
|
|||
|
Version under precisely this License, with the Modified Version filling the
|
|||
|
role of the Document, thus licensing distribution and modification of the
|
|||
|
Modified Version to whoever possesses a copy of it. In addition, you must do
|
|||
|
these things in the Modified Version:
|
|||
|
|
|||
|
A. Use in the Title Page (and on the covers, if any) a title distinct from
|
|||
|
that of the Document, and from those of previous versions (which should,
|
|||
|
if there were any, be listed in the History section of the Document). You
|
|||
|
may use the same title as a previous version if the original publisher of
|
|||
|
that version gives permission.
|
|||
|
|
|||
|
B. List on the Title Page, as authors, one or more persons or entities
|
|||
|
responsible for authorship of the modifications in the Modified Version,
|
|||
|
together with at least five of the principal authors of the Document (all
|
|||
|
of its principal authors, if it has less than five).
|
|||
|
|
|||
|
C. State on the Title page the name of the publisher of the Modified
|
|||
|
Version, as the publisher.
|
|||
|
|
|||
|
D. Preserve all the copyright notices of the Document.
|
|||
|
|
|||
|
E. Add an appropriate copyright notice for your modifications adjacent to
|
|||
|
the other copyright notices.
|
|||
|
|
|||
|
F. Include, immediately after the copyright notices, a license notice giving
|
|||
|
the public permission to use the Modified Version under the terms of this
|
|||
|
License, in the form shown in the Addendum below.
|
|||
|
|
|||
|
G. Preserve in that license notice the full lists of Invariant Sections and
|
|||
|
required Cover Texts given in the Document's license notice.
|
|||
|
|
|||
|
H. Include an unaltered copy of this License.
|
|||
|
|
|||
|
I. Preserve the section entitled "History", and its title, and add to it an
|
|||
|
item stating at least the title, year, new authors, and publisher of the
|
|||
|
Modified Version as given on the Title Page. If there is no section
|
|||
|
entitled "History" in the Document, create one stating the title, year,
|
|||
|
authors, and publisher of the Document as given on its Title Page, then
|
|||
|
add an item describing the Modified Version as stated in the previous
|
|||
|
sentence.
|
|||
|
|
|||
|
J. Preserve the network location, if any, given in the Document for public
|
|||
|
access to a Transparent copy of the Document, and likewise the network
|
|||
|
locations given in the Document for previous versions it was based on.
|
|||
|
These may be placed in the "History" section. You may omit a network
|
|||
|
location for a work that was published at least four years before the
|
|||
|
Document itself, or if the original publisher of the version it refers to
|
|||
|
gives permission.
|
|||
|
|
|||
|
K. In any section entitled "Acknowledgements" or "Dedications", preserve the
|
|||
|
section's title, and preserve in the section all the substance and tone
|
|||
|
of each of the contributor acknowledgements and/or dedications given
|
|||
|
therein.
|
|||
|
|
|||
|
L. Preserve all the Invariant Sections of the Document, unaltered in their
|
|||
|
text and in their titles. Section numbers or the equivalent are not
|
|||
|
considered part of the section titles.
|
|||
|
|
|||
|
M. Delete any section entitled "Endorsements". Such a section may not be
|
|||
|
included in the Modified Version.
|
|||
|
|
|||
|
N. Do not retitle any existing section as "Endorsements" or to conflict in
|
|||
|
title with any Invariant Section.
|
|||
|
|
|||
|
|
|||
|
If the Modified Version includes new front-matter sections or appendices that
|
|||
|
qualify as Secondary Sections and contain no material copied from the
|
|||
|
Document, you may at your option designate some or all of these sections as
|
|||
|
invariant. To do this, add their titles to the list of Invariant Sections in
|
|||
|
the Modified Version's license notice. These titles must be distinct from any
|
|||
|
other section titles.
|
|||
|
|
|||
|
You may add a section entitled "Endorsements", provided it contains nothing
|
|||
|
but endorsements of your Modified Version by various parties--for example,
|
|||
|
statements of peer review or that the text has been approved by an
|
|||
|
organization as the authoritative definition of a standard.
|
|||
|
|
|||
|
You may add a passage of up to five words as a Front-Cover Text, and a
|
|||
|
passage of up to 25 words as a Back-Cover Text, to the end of the list of
|
|||
|
Cover Texts in the Modified Version. Only one passage of Front-Cover Text and
|
|||
|
one of Back-Cover Text may be added by (or through arrangements made by) any
|
|||
|
one entity. If the Document already includes a cover text for the same cover,
|
|||
|
previously added by you or by arrangement made by the same entity you are
|
|||
|
acting on behalf of, you may not add another; but you may replace the old
|
|||
|
one, on explicit permission from the previous publisher that added the old
|
|||
|
one.
|
|||
|
|
|||
|
The author(s) and publisher(s) of the Document do not by this License give
|
|||
|
permission to use their names for publicity for or to assert or imply
|
|||
|
endorsement of any Modified Version.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
5. COMBINING DOCUMENTS
|
|||
|
|
|||
|
You may combine the Document with other documents released under this
|
|||
|
License, under the terms defined in section 4 above for modified versions,
|
|||
|
provided that you include in the combination all of the Invariant Sections of
|
|||
|
all of the original documents, unmodified, and list them all as Invariant
|
|||
|
Sections of your combined work in its license notice.
|
|||
|
|
|||
|
The combined work need only contain one copy of this License, and multiple
|
|||
|
identical Invariant Sections may be replaced with a single copy. If there are
|
|||
|
multiple Invariant Sections with the same name but different contents, make
|
|||
|
the title of each such section unique by adding at the end of it, in
|
|||
|
parentheses, the name of the original author or publisher of that section if
|
|||
|
known, or else a unique number. Make the same adjustment to the section
|
|||
|
titles in the list of Invariant Sections in the license notice of the
|
|||
|
combined work.
|
|||
|
|
|||
|
In the combination, you must combine any sections entitled "History" in the
|
|||
|
various original documents, forming one section entitled "History"; likewise
|
|||
|
combine any sections entitled "Acknowledgements", and any sections entitled
|
|||
|
"Dedications". You must delete all sections entitled "Endorsements."
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
6. COLLECTIONS OF DOCUMENTS
|
|||
|
|
|||
|
You may make a collection consisting of the Document and other documents
|
|||
|
released under this License, and replace the individual copies of this
|
|||
|
License in the various documents with a single copy that is included in the
|
|||
|
collection, provided that you follow the rules of this License for verbatim
|
|||
|
copying of each of the documents in all other respects.
|
|||
|
|
|||
|
You may extract a single document from such a collection, and distribute it
|
|||
|
individually under this License, provided you insert a copy of this License
|
|||
|
into the extracted document, and follow this License in all other respects
|
|||
|
regarding verbatim copying of that document.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
7. AGGREGATION WITH INDEPENDENT WORKS
|
|||
|
|
|||
|
A compilation of the Document or its derivatives with other separate and
|
|||
|
independent documents or works, in or on a volume of a storage or
|
|||
|
distribution medium, does not as a whole count as a Modified Version of the
|
|||
|
Document, provided no compilation copyright is claimed for the compilation.
|
|||
|
Such a compilation is called an "aggregate", and this License does not apply
|
|||
|
to the other self-contained works thus compiled with the Document, on account
|
|||
|
of their being thus compiled, if they are not themselves derivative works of
|
|||
|
the Document.
|
|||
|
|
|||
|
If the Cover Text requirement of section 3 is applicable to these copies of
|
|||
|
the Document, then if the Document is less than one quarter of the entire
|
|||
|
aggregate, the Document's Cover Texts may be placed on covers that surround
|
|||
|
only the Document within the aggregate. Otherwise they must appear on covers
|
|||
|
around the whole aggregate.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
8. TRANSLATION
|
|||
|
|
|||
|
Translation is considered a kind of modification, so you may distribute
|
|||
|
translations of the Document under the terms of section 4. Replacing
|
|||
|
Invariant Sections with translations requires special permission from their
|
|||
|
copyright holders, but you may include translations of some or all Invariant
|
|||
|
Sections in addition to the original versions of these Invariant Sections.
|
|||
|
You may include a translation of this License provided that you also include
|
|||
|
the original English version of this License. In case of a disagreement
|
|||
|
between the translation and the original English version of this License, the
|
|||
|
original English version will prevail.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
9. TERMINATION
|
|||
|
|
|||
|
You may not copy, modify, sublicense, or distribute the Document except as
|
|||
|
expressly provided for under this License. Any other attempt to copy, modify,
|
|||
|
sublicense or distribute the Document is void, and will automatically
|
|||
|
terminate your rights under this License. However, parties who have received
|
|||
|
copies, or rights, from you under this License will not have their licenses
|
|||
|
terminated so long as such parties remain in full compliance.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
10. FUTURE REVISIONS OF THIS LICENSE
|
|||
|
|
|||
|
The Free Software Foundation may publish new, revised versions of the GNU
|
|||
|
Free Documentation License from time to time. Such new versions will be
|
|||
|
similar in spirit to the present version, but may differ in detail to address
|
|||
|
new problems or concerns. See [http://www.gnu.org/copyleft/] http://
|
|||
|
www.gnu.org/copyleft/.
|
|||
|
|
|||
|
Each version of the License is given a distinguishing version number. If the
|
|||
|
Document specifies that a particular numbered version of this License "or any
|
|||
|
later version" applies to it, you have the option of following the terms and
|
|||
|
conditions either of that specified version or of any later version that has
|
|||
|
been published (not as a draft) by the Free Software Foundation. If the
|
|||
|
Document does not specify a version number of this License, you may choose
|
|||
|
any version ever published (not as a draft) by the Free Software Foundation.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
|
|||
|
How to use this License for your documents
|
|||
|
|
|||
|
To use this License in a document you have written, include a copy of the
|
|||
|
License in the document and put the following copyright and license notices
|
|||
|
just after the title page:
|
|||
|
|
|||
|
|
|||
|
Copyright (c) YEAR YOUR NAME. Permission is granted to copy, distribute
|
|||
|
and/or modify this document under the terms of the GNU Free Documentation
|
|||
|
License, Version 1.1 or any later version published by the Free Software
|
|||
|
Foundation; with the Invariant Sections being LIST THEIR TITLES, with the
|
|||
|
Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. A
|
|||
|
copy of the license is included in the section entitled "GNU Free
|
|||
|
Documentation License".
|
|||
|
|
|||
|
If you have no Invariant Sections, write "with no Invariant Sections" instead
|
|||
|
of saying which ones are invariant. If you have no Front-Cover Texts, write
|
|||
|
"no Front-Cover Texts" instead of "Front-Cover Texts being LIST"; likewise
|
|||
|
for Back-Cover Texts.
|
|||
|
|
|||
|
If your document contains nontrivial examples of program code, we recommend
|
|||
|
releasing these examples in parallel under your choice of free software
|
|||
|
license, such as the GNU General Public License, to permit their use in free
|
|||
|
software.
|