<navid="sidebar"class="sidebar"aria-label="Table of contents">
<divclass="sidebar-scrollbox">
<olclass="chapter"><liclass="chapter-item expanded affix "><ahref="zshguide.html">A User's Guide to the Z-Shell</a></li><liclass="chapter-item expanded "><ahref="zshguide01.html"><strongaria-hidden="true">1.</strong> A short introduction</a></li><liclass="chapter-item expanded "><ahref="zshguide02.html"class="active"><strongaria-hidden="true">2.</strong> What to put in your startup files</a></li><liclass="chapter-item expanded "><ahref="zshguide03.html"><strongaria-hidden="true">3.</strong> Dealing with basic shell syntax</a></li><liclass="chapter-item expanded "><ahref="zshguide04.html"><strongaria-hidden="true">4.</strong> The Z-Shell Line Editor</a></li><liclass="chapter-item expanded "><ahref="zshguide05.html"><strongaria-hidden="true">5.</strong> Substitutions</a></li><liclass="chapter-item expanded "><ahref="zshguide06.html"><strongaria-hidden="true">6.</strong> Completion, old and new</a></li><liclass="chapter-item expanded "><ahref="zshguide07.html"><strongaria-hidden="true">7.</strong> Modules and other bits and pieces Not written</a></li></ol>
<buttonid="sidebar-toggle"class="icon-button"type="button"title="Toggle Table of Contents"aria-label="Toggle Table of Contents"aria-controls="sidebar">
<ahref="print.html"title="Print this book"aria-label="Print this book">
<iid="print-button"class="fa fa-print"></i>
</a>
</div>
</div>
<divid="search-wrapper"class="hidden">
<formid="searchbar-outer"class="searchbar-outer">
<inputtype="search"id="searchbar"name="searchbar"placeholder="Search this book ..."aria-controls="searchresults-outer"aria-describedby="searchresults-header">
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<p><spanid="init"></span><spanid="l6"></span></p>
<h1id="chapter-2-what-to-put-in-your-startup-files"><aclass="header"href="#chapter-2-what-to-put-in-your-startup-files">Chapter 2: What to put in your startup files</a></h1>
<p>There are probably various changes you want to make to the shell's
behaviour. All shells have `startup' files, containing commands which
are executed as soon as the shell starts. Like many others, zsh allows
each user to have their own startup files. In this chapter, I discuss
the sorts of things you might want to put there. This will serve as an
introduction to what the shell does; by the end, you should have an
inkling of many of the things which will be discussed in more detail
later on and why they are interesting. Sometimes you will find out more
than you want to know, such as how zsh differs from other shells you're
not going to use. Explaining the differences here saves me having to lie
about how the shell works and correcting it later on: most people will
simply want to know how the shell normally works, and note that there
are other ways of doing it.</p>
<p><spanid="l7"></span></p>
<h2id="21-types-of-shell-interactive-and-login-shells"><aclass="header"href="#21-types-of-shell-interactive-and-login-shells">2.1: Types of shell: interactive and login shells</a></h2>
<p>First, you need to know what is meant by an <strong>interactive</strong> and a
<strong>login</strong> shell. Basically, the shell is just there to take a list of
commands and run them; it doesn't really care whether the commands are
in a file, or typed in at the terminal. In the second case, when you are
typing at a prompt and waiting for each command to run, the shell is
<strong>interactive</strong>; in the other case, when the shell is reading commands
from a file, it is, consequently, <strong>non-interactive</strong>. A list of
commands used in this second way --- typically by typing something like
<code>zsh filename</code>, although there are shortcuts --- is called a <strong>script</strong>,
as if the shell was acting in a play when it read from it (and shells
can be real hams when it comes to playacting). When you start up a
script from the keyboard, there are actually two zsh's around: the
interactive one you're typing at, which is waiting for another,
non-interactive one to finish running the script. Almost nothing that
happens in the second one affects the first; they are different copies
of zsh.</p>
<p>Remember that when I give examples for you to type, I often show them as
they would appear in a script, without prompts in front. What you
actually see on the screen if you type them in will have a lot more in
front.</p>
<p>When you first log into the computer, the shell you are presented with
is interactive, but it is also a login shell. If you type `<code>zsh</code>', it
starts up a new interactive shell: because you didn't give it the name
of a file with commands in, it assumes you are going to type them
interactively. Now you've got two interactive shells at once, one
waiting for the other: it doesn't sound all that useful, but there are
times when you are going to make some radical changes to the shell's
settings temporarily, and the easiest thing to do is to start another
shell, do what you want to do, and exit back to the original, unaltered,
shell --- so it's not as stupid as it sounds.</p>
<p>However, that second shell will not be a login shell. How does zsh know
the difference? Well, the programme that logs you in after you type your
password (called, predictably, <strong>login</strong>), actually sticks a `<code>-</code>' in
front of the name of the shell, which zsh recognises. The other way of
making a shell a login shell is to run it yourself with the option <code>-l</code>;
typing `<code>zsh -l</code>' will start a zsh that also thinks it's a login shell,
and later I'll explain how to turn on options within the shell, which
you can do with the login option too. Otherwise, any zsh you start
yourself will not be a login shell. If you are using X-Windows, and have
a terminal emulator such as xterm running a shell, that is probably not
a login shell. However, it's actually possible to get xterm to start a
login shell by giving it the option <code>-ls</code>, so if you type `<code>xterm -ls &</code>', you will get a window running a login shell (the <code>&</code> means the
shell in the first window doesn't wait for it to finish).</p>
<p>The first main difference between a login shell and any other
interactive shell is the one to do with startup files, described below.
The other one is what you do when you're finished. With a login shell
you can type `<code>logout</code>' to exit the shell; with another you type
`<code>exit</code>'. However, `<code>exit</code>' works for all shells, interactive,
non-interactive, login, whatever, so a lot of people just use that. In
fact, the only difference is that `<code>logout</code>' will tell you `<code>not login shell</code>' if you use it anywhere else and fail to exit. The command
`<code>bye</code>' is identical to `<code>exit</code>', only shorter and less standard. So
my advice is just to use `<code>exit</code>'.</p>
<p>As somebody pointed out to me recently, login shells don't have to be
interactive. You can always start a shell in the two ways that make it a
login shell; the ways that make it an interactive shell or not are
independent. In fact, some start-up scripts for windowing systems run a
non-interactive login shell to incorporate definitions from the
appropriate login scripts before executing the commands to start the
windowing session.</p>
<p><spanid="l8"></span></p>
<h3id="211-what-is-a-login-shell-simple-tests"><aclass="header"href="#211-what-is-a-login-shell-simple-tests">2.1.1: What is a login shell? Simple tests</a></h3>
<p>Telling if the shell you are looking at is interactive is usually easy:
if there's a prompt, it's interactive. As you may have gathered, telling
if it's a login shell is more involved because you don't always know how
the shell was started or if the option got changed. If you want to know,
you can type the following (one line at a time if you like, see below),</p>
<pre><code> if [[ -o login ]]; then
print yes
else
print no
fi
</code></pre>
<p>which will print `yes' or `no' according to whether it's a login shell
or not; the syntax will be explained as we go along. There are shorter
ways of doing it, but this illustrates the commonest shell syntax for
testing things, something you probably often want to do in a startup
file. What you're testing goes inside the `<code>[[ ... ]]</code>'; in this case,
the <code>-o</code> tells the shell to test an option, here <code>login</code>. The next line
says what to do if the test succeeded; the line after the `<code>else</code>' what
to do if the test failed. This syntax is virtually identical to ksh; in
this guide, I will not give exhaustive details on the tests you can
perform, since there are many of them, but just show some of the most
useful. As always, see the manual --- in this case, `Conditional
Expressions' in the <code>zshmisc</code> manual pages.</p>
<p>Although you usually know when a shell is interactive, in fact you can
test that in exactly the same way, too: just use `<code>[[ -o interactive ]]</code>'. This is one option you can't change within the shell; if you turn
off reading from the keyboard, where is the shell supposed to read from?
But you can at least test it.</p>
<p>Aside for beginners in shell programming: maybe the semicolon looks a
bit funny; that's because the `<code>then</code>' is really a separate command.
The semicolon is just instead of putting it on a new line; the two are
interchangeable. In fact, I could have written,</p>
<pre><code> if [[ -o login ]]; then; print yes; else; print no; fi
</code></pre>
<p>which does exactly the same thing. I could even have missed out the
semicolons after `<code>then</code>' and `<code>else</code>', because the shell knows that a
command must come after each of those --- though the semicolon or
newline <em>before</em> the <code>then</code> is often important, because the shell does
<code>not</code> know a command has to come next, and might mix up the <code>then</code> with
the arguments of the command after the `<code>if</code>': it may look odd, but the
`<code>[[</code><em>...</em><code>]]</code>' is actually a command. So you will see various ways
of dividing up the lines in shell programmes. You might also like to
know that <code>print</code> is one of the builtin commands referred to before; in
other words, the whole of that chunk of programme is executed by the
shell itself. If you're using a newish version of the shell, you will
notice that zsh tells you what it's waiting for, i.e. a `<code>then</code>' or an
`<code>else</code>' clause --- see the explanation of <code>$PS2</code> below for more on
this. Finally, the spaces I put before the `<code>print</code>' commands were
simply to make it look prettier; any number of spaces can appear before,
after, or between commands and arguments, as long as there's at least
one between ordinary words (the semicolon is recognised as special, so
you don't need one before that, though it's harmless if you do put one
in).</p>
<p>Second aside for users of sh: you may remember that tests in sh used a
single pair of brackets, `<code>if [ ... ]; then ...</code>', or equivalently as a
command called <strong>test</strong>, `<code>if test ...; then ...</code>'. The Korn shell was
deliberately made to be different, and zsh follows that. The reason is
that `<code>[[</code>' is treated specially, which allows the shell to do some
extra checks and allows more natural syntax. For example, you may know
that in sh it's dangerous to test a parameter which may be empty: `[
$var = foo ]' will fail if <code>$var</code> is empty, because in that case the
word is missed out and the shell never knows it was supposed to be
there; with `<code>[[</code><em>...</em><code>]]</code>', this is quite safe because the shell is
aware there's a word before the `<code>=</code>', even if it's empty. Also, you
can use `<code>&&</code>' and `<code>||</code>' to mean logical `and' and `or', which
agrees with the usual UNIX/C convention; in sh, they would have been
taken as starting a new command, not as part of the test, and you have
to use the less clear `<code>-a</code>' and `<code>-o</code>'. Actually, zsh provides the
old form of test for backward compatibility, but things will work a lot
more smoothly if you don't use it.</p>
<p><spanid="l9"></span></p>
<h2id="22-all-the-startup-files"><aclass="header"href="#22-all-the-startup-files">2.2: All the startup files</a></h2>
<p>Now here's a list of the startup files and when they're run. You'll see
they fall into two classes: those in the <code>/etc</code> directory, which are put
there by the system administrator and are run for all users, and those
in your home directory, which zsh, like many shells, allows you to
abbreviate to a `<code>~</code>'. It's possible that the latter files are
somewhere else; type `<code>print $ZDOTDIR</code>' and if you get something other
than a blank line, or an error message telling you the parameter isn't
set, it's telling you a directory other than `<code>~</code>' where your startup
files live. If <code>$ZDOTDIR</code> (another parameter) is not already set, you
<p>It's time to talk about options, since I've mentioned them several
times. Each option describes one particular shell behaviour; they are
all Boolean, i.e. can either be on or off, with no other state. They
have short names and in the documentation and this guide they are
written in uppercase with underscores separating the bits (except in
actual code, where I'll write them in the short form). However, neither
of those is necessary. In fact, <code>NO_RCS</code> and <code>norcs</code> and <code>__N_o_R_c_S__</code>
mean the same thing and are all accepted by the shell.</p>
<p>The second thing is that an option with `<code>no</code>' in front just means the
opposite of the option without. I could also have written the test `<code>[[ ! -o norcs ]]</code>' as `<code>[[ -o rcs ]]</code>'; the `<code>!</code>' means `not', as in C.
You can only have one `<code>no</code>'; `<code>nonorcs</code>' is meaningless.
Unfortunately, there is an option `<code>NOMATCH</code>' which has `<code>no</code>' as part
of its basic name, so in this case the opposite really is
`<code>NO_NOMATCH</code>'; <code>NOTIFY</code>, of course, is also a full name in its own
right.</p>
<p>The usual way to set and unset options is with the commands <strong>setopt</strong>
and <strong>unsetopt</strong> which take a string of option names. Some options also
have flags, like the `<code>-f</code>' for <code>NO_RCS</code>, which these commands also
accept, but it's much clearer to use the full name and the extra time
and space is negligible. The command `<code>set -o</code>' is equivalent to
<code>setopt</code>; this comes from ksh. Note that <code>set</code> with no `<code>-o</code>' does
something else --- that sets the positional parameters, which is zsh's
way of passing arguments to scripts and functions.</p>
<p>Almost everybody sets some options in their startup files. Since you
want them in every interactive shell, at the least, the choice is
between putting them in <code>~/.zshrc</code> or <code>~/.zshenv</code>. The choice really
depends on how you use non-interactive shells. They can be started up in
unexpected places. For example, if you use Emacs and run commands from
inside it, such as <strong>grep</strong>, that will start a non-interactive shell,
and may require some options. My rule of thumb is to put as many options
as possible into <code>~/.zshrc</code>, and transfer them to <code>~/.zshenv</code> if I find
I need them there. Some purists object to setting options in <code>~/.zshenv</code>
at all, since it affects scripts; but, as I've already hinted, you have
to work a bit harder to make sure scripts are unaffected by that sort of
thing anyway. In the following, I just assume they are going to be in
<p>Arrays are useful when the shell needs to keep a whole series of
different things together, so we'll meet some you may want to put in a
startup file. Users of ksh will have noticed that things are a bit
different in zsh, but for now I'll just assume you're using the normal
zsh way of doing things.</p>
<p><spanid="l13"></span></p>
<h2id="25-what-to-put-in-your-startup-files"><aclass="header"href="#25-what-to-put-in-your-startup-files">2.5: What to put in your startup files</a></h2>
<p>At the last count there were over 130 options and several dozen
parameters which are special to the shell, and many of them deal with
things I won't talk about till much later. But as a guide to get you
started, and an indication of what's to come, here are some options and
parameters you might want to think about setting in <code>~/.zshrc</code>.</p>
<p><spanid="l14"></span></p>
<h3id="251-compatibility-options-sh_word_split-and-others"><aclass="header"href="#251-compatibility-options-sh_word_split-and-others">2.5.1: Compatibility options: <code>SH_WORD_SPLIT</code> and others</a></h3>
<p>I've already mentioned that zsh works differently from ksh, its nearest
standard relative, and that some of these differences can be confusing
to new users, for example the use of arrays. Some options like
<code>KSH_ARRAYS</code> exist to allow you to have things work the ksh way. Most of
these are fairly finnicky, but one catches out a lot of people. Above, I
said that after</p>
<pre><code> foo='This is a parameter.'
</code></pre>
<p>then <code>$foo</code> would be treated as one word. In traditional Bourne-like
shells including sh, ksh and bash, however, the shell will split <code>$foo</code>
on any spaces it finds. So if you run a command</p>
<pre><code> command $foo
</code></pre>
<p>then in zsh the command gets a single argument `<code>This is a parameter.</code>', but in the other shells it gets the first argument
`<code>This</code>', the second argument `<code>is</code>', and so on. If you like this, or
are so used to it it would be confusing to change, you should set the
option <code>SH_WORD_SPLIT</code> in your <code>~/.zshrc</code>. Most experienced zsh users
use arrays when they want word splitting, since as I explained you have
control over what is split and what is not; that's why <code>SH_WORD_SPLIT</code>
is not set by default. Users of other shells just get used to putting
things in double quotes,</p>
<pre><code> command "$foo"
</code></pre>
<p>which, unlike single quotes, allow the `<code>$</code>' to remain special, and
have the side effect that whatever is in quotes will remain a single
word (though there's an exception to that, too: the parameter <code>$@</code>).</p>
<p>There are a lot of other options doing similar things to keep users of
standard shells happy. Many of them simply turn features off, because
the other shell doesn't have them and hence unexpected things might
happen, or simply tweak a feature which is a little different or doesn't
usually matter. Currently such options include <code>NO_BANG_HIST</code>,
<p>Zsh has the old csh mechanism for referring to words on a previous
command line using a `<code>!</code>'; it's less used, now the editor is more
powerful, but is still a convenient shorthand for extracting short bits
from the previous line. This mechanism is sometimes called
<strong>bang-history</strong>, since busy people sometimes like to say `<code>!</code>' as
`bang'. This option affects how a single `<code>!</code>' works. For example,</p>
<pre><code> % print foo bar
% print open closed
% print !-2:1 !:2
</code></pre>
<p>In the last line, `<code>!-2</code>' means two entries ago, i.e. the line `<code>print foo bar</code>'. The `<code>:1</code>' chooses the first word after the command, i.e.
`<code>foo</code>'. In the second expression, no number is given after the `<code>!</code>'.
Usually zsh interprets that to mean that the same item just selected, in
this case -2, should be used. With <code>CSH_JUNKIE_HISTORY</code> set, it refers
instead to the last command. Note that if you hadn't given that -2, it
would refer to the last command in any case, although the explicit way
of referring to the last command is `<code>!!</code>' --- you have to use that if
there are no `<code>:</code>' bits following. In summary, zsh usually gives you
`<code>print foo bar</code>'; with <code>CSH_JUNKIE_HISTORY</code> you get `<code>print foo closed</code>'.</p>
<p>There's another option controlling this, <code>BANG_HIST</code>. If you unset that,
the mechanism won't work at all. There's also a parameter, <code>$histchars</code>.
The first character is the main history expansion character, normally
`<code>!</code>' of course; the second is for rapid substitutions (normally `<code>^</code>'
--- use of this is described below); the third is the character
introducing comments, normally `<code>#</code>'. Changing the third character is
definitely not recommended. There's little real reason to change any.</p>
<p>Here just for completeness. Csh and friends don't allow multiline
quotes, as zsh does; if you don't finish a pair of quotes before a new
line, csh will complain. This option makes zsh do the same. But
multi-line quotes are very useful and very common in zsh scripts and
functions; this is only for people whose minds have been really screwed
up by using csh.</p>
<p><spanid="l16"></span></p>
<h3id="253-the-history-mechanism-types-of-history"><aclass="header"href="#253-the-history-mechanism-types-of-history">2.5.3: The history mechanism: types of history</a></h3>
<p>The name `history mechanism' refers to the fact that zsh keeps a
`history' of the commands you have typed. There are three ways of
getting these back; all these use the same set of command lines, but the
mechanisms for getting at them are rather different. For some reason,
items in the history list (a complete line of input typed and executed
at once) have become known as `events'.</p>
<p><strong>Editing the history directly</strong></p>
<p>First, you can use the editor; usually hitting up-arrow will take you to
the previous line, and down-arrow takes you back. This is usually the
easiest way, since you can see exactly what you're doing. I will say a
great deal more about the editor in <ahref="zshguide04.html#zle">chapter 4</a>;
the first thing to know is that its basic commands work either like
emacs, or like vi, so if you know one of those, you can start editing
lines straight away. The shell tries to guess whether to use emacs or vi
from the environment variables <code>$VISUAL</code> or <code>$EDITOR</code>, in that order;
these traditionally hold the name of your preferred editor for
programmes which need you to edit text. In the old days, <code>$VISUAL</code> was a
full-screen editor and <code>$EDITOR</code> a line editor, like <code>ed</code> of blessed
memory, but the distinction is now very blurred. If either contains the
string <code>vi</code>, the line editor will start in vi mode, else it will start
in emacs mode. If you're in the wrong mode, `<code>bindkey -e</code>' in
<code>~/.zshrc</code> takes you to emacs mode and `<code>bindkey -v</code>' to vi mode. For
vi users, the thing to remember is that you start in insert mode, so
type `<code>ESC</code>' to be able to enter vi commands.</p>
<p><strong>`Bang'-history</strong></p>
<p>Second, you can use the csh-style `bang-history' mechanism (unless you
have set the option <code>NO_BANG_HIST</code>); the `bang' is the exclamation
mark, `!', also known as `pling' or `shriek' (or factorial, but
that's another story). Thus `<code>!!</code>' retrieves the last command line and
executes it; `<code>!-2</code>' retrieves the second last. You can select words:
`<code>!!:1</code>' picks the first word after the command of the last command (if
you were paying attention above, you will note you just need one `<code>!</code>'
in that case); <code>0</code> after colon would pick the command word itself;
`<code>*</code>' picks all arguments after the command; `<code>$</code>' picks the last
word. You can even have ranges: `<code>!!:1-3</code>' picks those three words, and
things like `<code>!!:3-$</code>' work too.</p>
<p>After the word selector, you can have a second set of colons and then
some special commands called <strong>modifiers</strong> --- these can be very useful
to remember, since they can be applied to parameters and file patterns
to, so here's some more details. The `<code>:t</code>' (tail) modifier picks the
last part of a filename, everything after the last slash; conversely,
`<code>:h</code>' (head) picks everything before that. So with a history entry,</p>
<pre><code> % print /usr/bin/cat
/usr/bin/cat
% print !!:t
print cat
cat
</code></pre>
<p>Note two things: first, the bang-history mechanism always prints what
it's about to execute. Secondly, you don't need the word selector; the
shell can tell that the `<code>:t</code>' is a modifier, and assumes you want it
applied to the entire previous command. (Be careful here, since actually
the <code>:t</code> will reduce the expression to everything after the last slash
in <em>any</em> word, which is a little unexpected.)</p>
<p>With parameters:</p>
<pre><code> % foo=/usr/bin/cat
% print ${foo:h}
/usr/bin
</code></pre>
<p>(you can usually omit the `<code>{</code>' and `<code>}</code>', but it's clearer and safer
with them). And finally with files --- this won't work if you set
<code>NO_BARE_GLOB_QUAL</code> for sh-like behaviour:</p>
<pre><code> % print /usr/bin/cat(:t)
cat
</code></pre>
<p>where you need the parentheses to tell the shell the `<code>:t</code>' isn't just
part of the file name.</p>
<p>For a complete list, see the <code>zshexpn</code> manual, or the section
<code>Modifiers</code> in the printed or Info versions of the manual, but here are
a few more of the most useful. `<code>:r</code>' removes the suffix of a file,
turning <code>file.c</code> into <code>file</code>; `<code>:l</code>' and `<code>:u</code>' make the word(s) all
lowercase or all uppercase; `<code>:s/foo/bar/</code>' substitutes the first
occurrence of <code>foo</code> with <code>bar</code> in the word(s); `<code>:gs/foo/bar</code>'
substitutes all occurrences (the `<code>g</code>' stands for global); `<code>:&</code>'
repeats the last such substitution, even if you did it on a previous
line; `<code>:g&</code>' also works. So</p>
<pre><code> % print this is this line
this is this line
% !!:s/this/that/
print that is this line
that is this line
% print this is no longer this line
this is no longer this line
% !!:g&
print that is no longer that line
that is no longer that line
</code></pre>
<p>Finally, there is a shortcut: <code>^old^new^</code> is exactly equivalent to
<code>!!:s/old/new/</code>; you can even put another modifier after it. The `<code>^</code>'
is actually the second character of <code>$histchars</code> mentioned above. You
can miss out the last `<code>^</code>' if there's nothing else to follow it. By
the way, you can put modifiers together, but each one needs the colon
with it: <code>:t:r</code> applied to `<code>dir/file.c</code>' produces `<code>file</code>', and
repeated applications of <code>:h</code> get you shorter and shorter paths.</p>
<p>Before we leave bang-history, note the option <code>HIST_VERIFY</code>. If that's
set, then after a substitution the line appears again with the changes,
instead of being immediately printed and executed. As you just have to
type <code><RET></code> to execute it, this is a useful trick to save you executing
the wrong thing, which can easily happen with complicated bang-history
lines; I have this set myself.</p>
<p>And one last tip: the shell's expansion and completion, which I will
enthuse about at length later on, allows you to expand bang-history
references straight away by hitting <code>TAB</code> immediately after you've typed
the complete reference, and you can usually type control together with
slash (on some keyboards, you are restricted to <code>^Xu</code>) to put it back
the way it was if you don't like the result --- this is part of the
editor's `undo' feature.</p>
<p><strong>Ksh-style history commands</strong></p>
<p>The third form of history uses the <code>fc</code> builtin. It's the most
cumbersome: you have to tell the command which complete lines to
execute, and may be given a chance to edit them first (but using an
external editor, not in the shell). You probably won't use it that way,
but there are three things which are actually controlled by <code>fc</code> which
you might use: first, the `<code>r</code>' command repeats the last command
(ignoring <code>r</code>'s), which is a bit like `<code>!!</code>'. Secondly, the command
called `<code>history</code>' is also really <code>fc</code> in disguise. It gives you a list
of recent commands. They have numbers next to them; you can use these
with bang-history instead of using negative numbers to count backward in
the way I originally explained, the advantage being they don't change as
you enter more commands. You can give ranges of numbers to <code>history</code>,
the first number for where to start listing, and the second where to
stop: a particular example is `<code>history 1</code>', which lists all commands
(even if the first command it still remembers is higher than 1; it just
silently omits all those). The third use of <code>fc</code> is for reading and
writing your history so you can keep it between sessions.</p>
<p><spanid="l17"></span></p>
<h3id="254-setting-up-history"><aclass="header"href="#254-setting-up-history">2.5.4: Setting up history</a></h3>
<p>In fact, the shell is able to read and write history without being told.
You need to tell it where to save the history, however, and for that you
have to set the parameter <code>$HISTFILE</code> to the name of the file you want
to use (a common choice is `<code>~/.history</code>'). Next, you need to set the
parameter <code>$SAVEHIST</code> to the number of lines of your history you want
saved. When these two are set, the shell will read <code>$HISTSIZE</code> lines
from <code>$HISTFILE</code> at the start of an interactive session, and save the
last <code>$SAVEHIST</code> lines you executed at the end of the session. For it to
read or write in the middle, you will either need to set one of the
options described below (<code>INC_APPEND_HISTORY</code> and <code>SHARE_HISTORY</code>), or
use the <code>fc</code> command: <code>fc -R</code> and <code>fc -W</code> read and write the history
respectively, while <code>fc -A</code> appends it to the the file (although pruning
it if it's longer than <code>$SAVEHIST</code>); <code>fc -WI</code> and <code>fc -AI</code> are similar,
but the <code>I</code> means only write out events since the last time history was
written.</p>
<p>There is a third parameter <code>$HISTSIZE</code>, which determines the number of
lines the shell will keep within one session; except for special reasons
which I won't talk about, you should set <code>$SAVEHIST</code> to be no more than
<code>$HISTSIZE</code>, though it can be less. The default value for <code>$HISTSIZE</code> is
30, which is a bit stingy for the memory and disk space of today's
computers; zsh users often use anything up to 1000. So a simple set of
parameters to set in <code>.zshrc</code> is</p>
<pre><code> HISTSIZE=1000
SAVEHIST=1000
HISTFILE=~/.history
</code></pre>
<p>and that is enough to get things working. Note that you <em>must</em> set
<code>$SAVEHIST</code> and <code>$HISTFILE</code> for automatic reading and writing of history
lines to work.</p>
<p><spanid="l18"></span></p>
<h3id="255-history-options"><aclass="header"href="#255-history-options">2.5.5: History options</a></h3>
<p>There are also many options affecting history; these increased
substantially with version 3.1.6, which provided for the first time
<p>produces a red-on-white `<code>(1)</code>' if the previous programme exited with
status 1, but nothing if it exited with status 0, followed by a
yellow-on-black `<code>%</code>' or `<code>#</code>' if you are the superuser. Note the use
of the double quotes here to force the parameters to be expanded
straight away --- the escape sequences are fixed, so they don't need to
be re-extracted from the parameters every time the prompt is shown.</p>
<p>Even if your terminal does support colour, there's no guarantee all the
possibilities work, although the basic ANSI colour scheme is fairly
standard. The colours understood are: cyan, white, yellow, magenta,
black, blue, red, grey, green. You can also used `default', which puts
the terminal back how it was to begin with. In addition, you can use the
basic colours with the parameters <code>$bg_bold</code> and <code>$fg_bold</code> for bold
varieties of the colours and <code>$bg_no_bold</code> and <code>$fg_no_bold</code> to switch
explicitly back to non-bold.</p>
<p><strong>Themes</strong></p>
<p>There are also a set of themes provided as functions to set up your
prompt to various predefined possibilities. These make use of the
colours set up as described above. See the <code>zshcontrib</code> manual page for
how to do this (search for `prompt themes').</p>
<p><spanid="l20"></span></p>
<h3id="257-named-directories"><aclass="header"href="#257-named-directories">2.5.7: Named directories</a></h3>
<p>As already mentioned, `<code>~/</code>' at the start of a filename expands to your
home directory. More generally, `<code>~</code><em>user</em><code>/</code>' allows you to refer to
the home directory of any other user. Furthermore, zsh lets you define
your own named directories which use this syntax. The basic idea is
simple, since any parameter can be a named directory:</p>
<pre><code> dir=/tmp/mydir
print ~dir
</code></pre>
<p>prints `/tmp/mydir'. So far, this isn't any different from using the
parameter as <code>$dir</code>. The difference comes if you use the `<code>%~</code>'
construct, described above, in your prompt. Then when you change into
that directory, instead of seeing the message `<code>/tmp/mydir</code>', you will
see the abbreviation `<code>~dir</code>'.</p>
<p>The shell will not register the name of the directory until you force it
to by using `<code>~dir</code>' yourself at least once. You can do the following
in your <code>.zshrc</code>:</p>
<pre><code> dir=/tmp/mydir
bin=~/myprogs/bin
: ~dir ~bin
</code></pre>
<p>where `<code>:</code>' is a command that does nothing --- but its arguments are
checked for parameters and so on in the usual way, so that the shell can
put <code>dir</code> and <code>bin</code> into its list of named directories. A more simple
way of doing this is to set the option <code>AUTO_NAME_DIRS</code>; then any
parameter created which refers to a directory will automatically be
turned into a name. The directory must have an absolute path, i.e. its
expanded value, after turning any `<code>~</code>'s at the start into full paths,
must begin with a `<code>/</code>'. The parameter <code>$PWD</code>, which shows the current
directory, is protected from being turned into <code>~PWD</code>, since that would
tell you nothing.</p>
<p><spanid="l21"></span></p>
<h3id="258-go-faster-options-for-power-users"><aclass="header"href="#258-go-faster-options-for-power-users">2.5.8: `Go faster' options for power users</a></h3>
<p>Here are a few more random options you might want to set in your
<code>.zshrc</code>.</p>
<p><strong><code>NO_BEEP</code></strong></p>
<p>Normally zsh will beep if it doesn't like something. This can get
extremely annoying; `<code>setopt nobeep</code>' will turn it off. I refer to this
informally as the <code>OPEN_PLAN_OFFICE_NO_VIGILANTE_ATTACKS</code> option.</p>
<p><strong><code>AUTO_CD</code></strong></p>
<p>If this option is set, and you type something with no arguments which
isn't a command, zsh will check to see if it's actually a directory. If
it is, the shell will change to that directory. So `<code>./bin</code>' on its own
is equivalent to `<code>cd ./bin</code>', as long as the directory `<code>./bin</code>'
really exists. This is particularly useful in the form `<code>..</code>', which
changes to the parent directory.</p>
<p><strong><code>CD_ABLE_VARS</code></strong></p>
<p>This is another way of saving typing when changing directory, though
only one character. If a directory doesn't exist when you try to change
to it, zsh will try and find a parameter of that name and use that
instead. You can also have a `<code>/</code>' and other bits after the parameter.
So `cd <code>foo/dir</code>', if there is no directory `<code>foo</code>' but there is a
parameter <code>$foo</code>, becomes equivalent to `cd <code>$foo/dir</code>'.</p>