2026 lines
128 KiB
HTML
2026 lines
128 KiB
HTML
<!DOCTYPE HTML>
|
|
<html lang="en" class="sidebar-visible no-js light">
|
|
<head>
|
|
<!-- Book generated using mdBook -->
|
|
<meta charset="UTF-8">
|
|
<title>What to put in your startup files - Zsh User's Guide</title>
|
|
|
|
|
|
<!-- Custom HTML head -->
|
|
|
|
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
|
<meta name="description" content="">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<meta name="theme-color" content="#ffffff" />
|
|
|
|
<link rel="icon" href="favicon.svg">
|
|
<link rel="shortcut icon" href="favicon.png">
|
|
<link rel="stylesheet" href="css/variables.css">
|
|
<link rel="stylesheet" href="css/general.css">
|
|
<link rel="stylesheet" href="css/chrome.css">
|
|
<link rel="stylesheet" href="css/print.css" media="print">
|
|
|
|
<!-- Fonts -->
|
|
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
|
|
<link rel="stylesheet" href="fonts/fonts.css">
|
|
|
|
<!-- Highlight.js Stylesheets -->
|
|
<link rel="stylesheet" href="highlight.css">
|
|
<link rel="stylesheet" href="tomorrow-night.css">
|
|
<link rel="stylesheet" href="ayu-highlight.css">
|
|
|
|
<!-- Custom theme stylesheets -->
|
|
<link rel="stylesheet" href="./theme/catppuccin.css">
|
|
<link rel="stylesheet" href="./theme/catppuccin-highlight.css">
|
|
|
|
</head>
|
|
<body>
|
|
<!-- Provide site root to javascript -->
|
|
<script type="text/javascript">
|
|
var path_to_root = "";
|
|
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
|
</script>
|
|
|
|
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
|
<script type="text/javascript">
|
|
try {
|
|
var theme = localStorage.getItem('mdbook-theme');
|
|
var sidebar = localStorage.getItem('mdbook-sidebar');
|
|
|
|
if (theme.startsWith('"') && theme.endsWith('"')) {
|
|
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
|
}
|
|
|
|
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
|
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
|
}
|
|
} catch (e) { }
|
|
</script>
|
|
|
|
<!-- Set the theme before any content is loaded, prevents flash -->
|
|
<script type="text/javascript">
|
|
var theme;
|
|
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
|
if (theme === null || theme === undefined) { theme = default_theme; }
|
|
var html = document.querySelector('html');
|
|
html.classList.remove('no-js')
|
|
html.classList.remove('light')
|
|
html.classList.add(theme);
|
|
html.classList.add('js');
|
|
</script>
|
|
|
|
<!-- Hide / unhide sidebar before it is displayed -->
|
|
<script type="text/javascript">
|
|
var html = document.querySelector('html');
|
|
var sidebar = 'hidden';
|
|
if (document.body.clientWidth >= 1080) {
|
|
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
|
sidebar = sidebar || 'visible';
|
|
}
|
|
html.classList.remove('sidebar-visible');
|
|
html.classList.add("sidebar-" + sidebar);
|
|
</script>
|
|
|
|
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
|
<div class="sidebar-scrollbox">
|
|
<ol class="chapter"><li class="chapter-item expanded affix "><a href="zshguide.html">A User's Guide to the Z-Shell</a></li><li class="chapter-item expanded "><a href="zshguide01.html"><strong aria-hidden="true">1.</strong> A short introduction</a></li><li class="chapter-item expanded "><a href="zshguide02.html" class="active"><strong aria-hidden="true">2.</strong> What to put in your startup files</a></li><li class="chapter-item expanded "><a href="zshguide03.html"><strong aria-hidden="true">3.</strong> Dealing with basic shell syntax</a></li><li class="chapter-item expanded "><a href="zshguide04.html"><strong aria-hidden="true">4.</strong> The Z-Shell Line Editor</a></li><li class="chapter-item expanded "><a href="zshguide05.html"><strong aria-hidden="true">5.</strong> Substitutions</a></li><li class="chapter-item expanded "><a href="zshguide06.html"><strong aria-hidden="true">6.</strong> Completion, old and new</a></li><li class="chapter-item expanded "><a href="zshguide07.html"><strong aria-hidden="true">7.</strong> Modules and other bits and pieces Not written</a></li></ol>
|
|
</div>
|
|
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
|
</nav>
|
|
|
|
<div id="page-wrapper" class="page-wrapper">
|
|
|
|
<div class="page">
|
|
<div id="menu-bar-hover-placeholder"></div>
|
|
<div id="menu-bar" class="menu-bar sticky bordered">
|
|
<div class="left-buttons">
|
|
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
|
<i class="fa fa-bars"></i>
|
|
</button>
|
|
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
|
<i class="fa fa-paint-brush"></i>
|
|
</button>
|
|
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
|
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="latte">Latte</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="frappe">Frappé</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="macchiato">Macchiato</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="mocha">Mocha</button></li>
|
|
</ul>
|
|
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
|
<i class="fa fa-search"></i>
|
|
</button>
|
|
</div>
|
|
|
|
<h1 class="menu-title">Zsh User's Guide</h1>
|
|
|
|
<div class="right-buttons">
|
|
<a href="print.html" title="Print this book" aria-label="Print this book">
|
|
<i id="print-button" class="fa fa-print"></i>
|
|
</a>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<div id="search-wrapper" class="hidden">
|
|
<form id="searchbar-outer" class="searchbar-outer">
|
|
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
|
</form>
|
|
<div id="searchresults-outer" class="searchresults-outer hidden">
|
|
<div id="searchresults-header" class="searchresults-header"></div>
|
|
<ul id="searchresults">
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
|
<script type="text/javascript">
|
|
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
|
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
|
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
|
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
|
});
|
|
</script>
|
|
|
|
<div id="content" class="content">
|
|
<main>
|
|
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
|
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
|
<p><strong>Table of Contents</strong> <em>generated with <a href="https://github.com/thlorenz/doctoc">DocToc</a></em></p>
|
|
<ul>
|
|
<li><a href="#chapter-2-what-to-put-in-your-startup-files">Chapter 2: What to put in your startup files</a>
|
|
<ul>
|
|
<li><a href="#21-types-of-shell-interactive-and-login-shells">2.1: Types of shell: interactive and login shells</a>
|
|
<ul>
|
|
<li><a href="#211-what-is-a-login-shell-simple-tests">2.1.1: What is a login shell? Simple tests</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#22-all-the-startup-files">2.2: All the startup files</a></li>
|
|
<li><a href="#23-options">2.3: Options</a></li>
|
|
<li><a href="#24-parameters">2.4: Parameters</a>
|
|
<ul>
|
|
<li><a href="#241-arrays">2.4.1: Arrays</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#25-what-to-put-in-your-startup-files">2.5: What to put in your startup files</a>
|
|
<ul>
|
|
<li><a href="#251-compatibility-options-sh_word_split-and-others">2.5.1: Compatibility options: <code>SH_WORD_SPLIT</code> and others</a></li>
|
|
<li><a href="#252-options-for-csh-junkies">2.5.2: Options for csh junkies</a></li>
|
|
<li><a href="#253-the-history-mechanism-types-of-history">2.5.3: The history mechanism: types of history</a></li>
|
|
<li><a href="#254-setting-up-history">2.5.4: Setting up history</a></li>
|
|
<li><a href="#255-history-options">2.5.5: History options</a></li>
|
|
<li><a href="#256-prompts">2.5.6: Prompts</a></li>
|
|
<li><a href="#257-named-directories">2.5.7: Named directories</a></li>
|
|
<li><a href="#258-%5Cgo-faster-options-for-power-users">2.5.8: `Go faster' options for power users</a></li>
|
|
<li><a href="#259-aliases">2.5.9: aliases</a></li>
|
|
<li><a href="#2510-environment-variables">2.5.10: Environment variables</a></li>
|
|
<li><a href="#2511-path">2.5.11: Path</a></li>
|
|
<li><a href="#2512-mail">2.5.12: Mail</a></li>
|
|
<li><a href="#2513-other-path-like-things">2.5.13: Other path-like things</a></li>
|
|
<li><a href="#2514-version-specific-things">2.5.14: Version-specific things</a></li>
|
|
<li><a href="#2515-everything-else">2.5.15: Everything else</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
|
<p><span id="init"></span><span id="l6"></span></p>
|
|
<h1 id="chapter-2-what-to-put-in-your-startup-files"><a class="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><span id="l7"></span></p>
|
|
<h2 id="21-types-of-shell-interactive-and-login-shells"><a class="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><span id="l8"></span></p>
|
|
<h3 id="211-what-is-a-login-shell-simple-tests"><a class="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><span id="l9"></span></p>
|
|
<h2 id="22-all-the-startup-files"><a class="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
|
|
won't want to set it without a good reason.</p>
|
|
<ul>
|
|
<li><strong><code>/etc/zshenv</code></strong><br />
|
|
Always run for every zsh.</li>
|
|
<li><strong><code>~/.zshenv</code></strong><br />
|
|
Usually run for every zsh (see below).</li>
|
|
<li><strong><code>/etc/zprofile</code></strong><br />
|
|
Run for login shells.</li>
|
|
<li><strong><code>~/.zprofile</code></strong><br />
|
|
Run for login shells.</li>
|
|
<li><strong><code>/etc/zshrc</code></strong><br />
|
|
Run for interactive shells.</li>
|
|
<li><strong><code>~/.zshrc</code></strong><br />
|
|
Run for interactive shells.</li>
|
|
<li><strong><code>/etc/zlogin</code></strong><br />
|
|
Run for login shells.</li>
|
|
<li><strong><code>~/.zlogin</code></strong><br />
|
|
Run for login shells.</li>
|
|
</ul>
|
|
<p>Now you know what login and interactive shells are, this should be
|
|
straightforward. You may wonder why there are both <code>~/.zprofile</code> and
|
|
<code>~/.zlogin</code>, when they are both for login shells: the answer is the
|
|
obvious one, that one is run before, one after <code>~/.zshrc</code>. This is
|
|
historical; Bourne-type shells run <code>/etc/profile</code>, and csh-type shells
|
|
run <code>~/.login</code>, and zsh tries to cover the bases with its own startup
|
|
files.</p>
|
|
<p>The complication is hinted at by the `see below'. The file
|
|
<code>/etc/zshenv</code>, as it says, is always run at the start of any zsh.
|
|
However, if the option <code>NO_RCS</code> is set (or, equivalently, the <code>RCS</code>
|
|
option is unset: I'll talk about options shortly, since they are
|
|
important in startup files), none of the others are run. The most common
|
|
way of setting this option is with a flag on the command line: if you
|
|
start the shell as `<code>zsh -f</code>', the option becomes set, so only
|
|
<code>/etc/zshenv</code> is run and the others are skipped. Often, scripts do this
|
|
as a way of trying to get a basic shell with no frills, as I'll describe
|
|
below; but if something is set in <code>/etc/zshenv</code>, there's no way to avoid
|
|
it. This leads to the First Law of Zsh Administration: put as little as
|
|
possible in the file <code>/etc/zshenv</code>, as every single zsh which starts up
|
|
has to read it. In particular, if the script assumes that only the basic
|
|
options are set and <code>/etc/zshenv</code> has altered them, it might well not
|
|
work. So, at the absolute least, you should probably surround any option
|
|
settings in <code>/etc/zshenv</code> with</p>
|
|
<pre><code> if [[ ! -o norcs ]]; then
|
|
... <commands to run if NO_RCS is not set,
|
|
such as setting options> ...
|
|
fi
|
|
</code></pre>
|
|
<p>and your users will be eternally grateful. Settings for interactive
|
|
shells, such as prompts, have no business in <code>/etc/zshenv</code> unless you
|
|
<em>really</em> insist that all users have them as defaults for every single
|
|
shell. Script writers who want to get round problems with options being
|
|
changed in <code>/etc/zshenv</code> should put `<code>emulate zsh</code>' at the top of the
|
|
script.</p>
|
|
<p>There are two files run at the end: <code>~/.zlogout</code> and <code>/etc/zlogout</code>, in
|
|
that order. As their names suggest, they are counterparts of the
|
|
<code>zlogin</code> files, and therefore are only run for login shells --- though
|
|
you can trick the shell by setting the <code>login</code> option. Note that whether
|
|
you use <code>exit</code>, <code>bye</code> or <code>logout</code> to leave the shell does not affect
|
|
whether these files are run: I wasn't lying (this time) when I said that
|
|
the error message was the only difference between <code>exit</code> and <code>logout</code>.
|
|
If you want to run a file at the end of any other type of shell, you can
|
|
do it another way:</p>
|
|
<pre><code> TRAPEXIT() {
|
|
# commands to run here, e.g. if you
|
|
# always want to run .zlogout:
|
|
if [[ ! -o login ]]; then
|
|
# don't do this in a login shell
|
|
# because it happens anyway
|
|
. ~/.zlogout
|
|
fi
|
|
}
|
|
</code></pre>
|
|
<p>If you put that in <code>.zshrc</code>, it will force <code>.zlogout</code> to be run at the
|
|
end of all interactive shells. Traps will be mentioned later, but this
|
|
is rather a one-off; it's really just a hack to get commands run at the
|
|
end of the shell. I won't talk about logout files, however, since
|
|
there's little that's standard to put in them; some people make them
|
|
clear the screen to remove sensitive information with the `<code>clear</code>'
|
|
command. Other than that, you might need to tidy a few files up when you
|
|
exit.</p>
|
|
<p><span id="l10"></span></p>
|
|
<h2 id="23-options"><a class="header" href="#23-options">2.3: Options</a></h2>
|
|
<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
|
|
<code>~/.zshrc</code>.</p>
|
|
<p><span id="l11"></span></p>
|
|
<h2 id="24-parameters"><a class="header" href="#24-parameters">2.4: Parameters</a></h2>
|
|
<p>One more thing you'll need to know about in order to write startup files
|
|
is parameters, also known as variables. These are mostly like variables
|
|
in other programming languages. Simple parameters can be stored like
|
|
this (an <strong>assignment</strong>):</p>
|
|
<pre><code> foo='This is a parameter.'
|
|
</code></pre>
|
|
<p>Note two things: first, there are no spaces around the `<code>=</code>'. If there
|
|
was a space before, zsh would think `<code>foo</code>' was the name of a command
|
|
to execute; if there was a space after it, it would assign an empty
|
|
string to the parameter <code>foo</code>. Second, note the use of quotes to stop
|
|
the spaces inside the string having the same effect. Single quotes, as
|
|
here, are the nuclear option of quotes: everything up to another single
|
|
quote is treated as a simple string --- newlines, equal signs,
|
|
unprintable characters, the lot, in this example all would be assigned
|
|
to the variable; for example,</p>
|
|
<pre><code> foo='This is a parameter.
|
|
This is still the same parameter.'
|
|
</code></pre>
|
|
<p>So they're the best thing to use until you know what you're doing with
|
|
double quotes, which have extra effects. Sometimes you don't need them,
|
|
for example,</p>
|
|
<pre><code> foo=oneword
|
|
</code></pre>
|
|
<p>because there's nothing in `<code>oneword</code>' to confuse the shell; but you
|
|
could still put quotes there anyway.</p>
|
|
<p>Users of csh should note that you don't use `<code>set</code>' to set parameters.
|
|
This is important because there is a <code>set</code> command, but it works
|
|
differently --- if you try `<code>set var="this wont't work"</code>', you won't
|
|
get an error but you won't set the parameter, either. Type `<code>print $1</code>'
|
|
to see what you did set instead.</p>
|
|
<p>To get back what was stored in a parameter, you use the name somewhere
|
|
on the command line with a `<code>$</code>' tacked on the front --- this is called
|
|
an <strong>expansion</strong>, or to be more precise, since there are other types of
|
|
expansion, a <strong>parameter expansion</strong>. For example, after the first
|
|
assignment above.</p>
|
|
<pre><code> print -- '$foo is "'$foo'"'
|
|
</code></pre>
|
|
<p>gives</p>
|
|
<pre><code> $foo is "This is a parameter."
|
|
</code></pre>
|
|
<p>so you can see what I meant about the effect of single quotes. Note the
|
|
asymmetry --- there is no `<code>$</code>' when assigning the parameter, but there
|
|
is a `<code>$</code>' in front to have it expanded it into the command line. You
|
|
may find the word `substitution' used instead of `expansion'
|
|
sometimes; I'll try and stick with the terminology in the manual.</p>
|
|
<p>Two more things while we're at it. First, why did I put `<code>-``-</code>' after
|
|
the <code>print</code>? That's because <strong>print</strong>, like many UNIX commands, can take
|
|
options after it which begin with a `<code>-</code>'. `<code>-``-</code>' says that there
|
|
are no more options; so if what you're trying to print begins with a
|
|
`<code>-</code>', it will still print out. Actually, in this case you can see it
|
|
doesn't, so you're safe; but it's a good habit to get into, and I wish I
|
|
had. As always in zsh, there are exceptions; for example, if you use the
|
|
<code>-R</code> option to print before the `<code>-``-</code>', it only recognizes BSD-style
|
|
options, which means it doesn't understand `<code>-``-</code>'. Indeed, zsh
|
|
programmers can be quite lax about standards and often use the old, but
|
|
now non-standard, single `<code>-</code>' to show there are no more options.
|
|
Currently, this works even after <code>-R</code>.</p>
|
|
<p>The next point is that I didn't put spaces between the single quotes and
|
|
the <code>$foo</code> and it was still expanded --- expansion happens anywhere the
|
|
parameter is not quoted; it doesn't have to be on its own, just
|
|
separated from anything which might make it look like a different
|
|
parameter. This is one of those things that can help make shell scripts
|
|
look so barbaric.</p>
|
|
<p>As well as defining your own parameters, there are also a number which
|
|
the shell sets itself, and some others which have a special effect when
|
|
you set them. All the above still applies, though. For the rest of this
|
|
guide, I will indicate parameters with the `<code>$</code>' stuck in front, to
|
|
remind you what they are, but you should remember that the `<code>$</code>' is
|
|
missing when you set them, or, indeed, any time when you're referring to
|
|
the name of the parameter instead of its value.</p>
|
|
<p><span id="l12"></span></p>
|
|
<h3 id="241-arrays"><a class="header" href="#241-arrays">2.4.1: Arrays</a></h3>
|
|
<p>There is a special type of parameter called an <strong>array</strong> which zsh
|
|
inherited from both ksh and csh. This is a slightly shaky marriage,
|
|
since some of the things those two shells do with them are not
|
|
compatible, and zsh has elements of both, so you need to be careful if
|
|
you've used arrays in either. The option <code>KSH_ARRAYS</code> is something you
|
|
can set to make them behave more like they do in ksh, but a lot of zsh
|
|
users write functions and scripts assuming it isn't set, so it can be
|
|
dangerous.</p>
|
|
<p>Unlike normal parameters (known as <strong>scalars</strong>), arrays have more than
|
|
one word in them. In the examples above, we made the parameter <code>$foo</code>
|
|
get a string with spaces in, but the spaces weren't significant. If we'd
|
|
done</p>
|
|
<pre><code> foo=(This is a parameter.)
|
|
</code></pre>
|
|
<p>(note the absence of quotes), it would have created an array. Again,
|
|
there must be no space between the `<code>=</code>' and the `(', though inside
|
|
the parentheses spaces separate words just like they do on a command
|
|
line. The difference isn't obvious if you try and print it --- it looks
|
|
just the same --- but now try this:</p>
|
|
<pre><code> print -- ${foo[4]}
|
|
</code></pre>
|
|
<p>and you get `<code>parameter.</code>'. The array stores the words separately, and
|
|
you can retrieve them separately by putting the number of the element of
|
|
the array in square brackets. Note also the braces `<code>{...}</code>' --- zsh
|
|
doesn't always require them, but they make things much clearer when
|
|
things get complicated, and it's never wrong to put them in: you could
|
|
have said `<code>${foo}</code>' when you wanted to print out the complete
|
|
parameter, and it would be treated identically to `<code>$foo</code>'. The braces
|
|
simply screen off the expansion from whatever else might be lying around
|
|
to confuse the shell. It's useful too in expressions like `<code>${foo}s</code>'
|
|
to keep the `<code>s</code>' from being part of the parameter name; and, finally,
|
|
with <code>KSH_ARRAYS</code> set, the braces are compulsory, though unfortunately
|
|
arrays are indexed from 0 in that case.</p>
|
|
<p>You can use quotes when defining arrays; as before, this protects
|
|
against the shell thinking the spaces are between different elements of
|
|
the array. Try:</p>
|
|
<pre><code> foo=('first element' 'second element')
|
|
print -- ${foo[2]}
|
|
</code></pre>
|
|
<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><span id="l13"></span></p>
|
|
<h2 id="25-what-to-put-in-your-startup-files"><a class="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><span id="l14"></span></p>
|
|
<h3 id="251-compatibility-options-sh_word_split-and-others"><a class="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>,
|
|
<code>BSD_ECHO</code> (sh only), <code>IGNORE_BRACES</code>, <code>INTERACTIVE_COMMENTS</code>,
|
|
<code>KSH_OPTION_PRINT</code>, <code>NO_MULTIOS</code>, <code>POSIX_BUILTINS</code>, <code>PROMPT_BANG</code>,
|
|
<code>SINGLE_LINE_ZLE</code> (I've written them how they would appear as an
|
|
argument to <code>setopt</code> to put the option the way the other shell expects,
|
|
so some have `<code>NO_</code>' in front). Most people probably won't change those
|
|
unless they notice something isn't working how they expect.</p>
|
|
<p>Some others have more noticeable effects. Here are a few of the ones
|
|
most likely to make you scratch your head if you're changing from
|
|
another Bourne-like shell.</p>
|
|
<p><strong><code>BARE_GLOB_QUAL</code>, <code>GLOB_SUBST</code>, <code>SH_FILE_EXPANSION</code>, <code>SH_GLOB</code>,
|
|
<code>KSH_GLOB</code></strong></p>
|
|
<p>These are all to do with how pattern matching works. You probably
|
|
already know that the pattern `<code>*.c</code>' will be expanded into all the
|
|
files in the current directory ending in `<code>.c</code>'. Simple uses like this
|
|
are the same in all shells, and the way filenames are expanded is often
|
|
referred to as `globbing' for historical reasons (apparently it stood
|
|
for `global replacement'), hence the name of some of these options.</p>
|
|
<p>However, zsh and ksh differ over more complicated patterns. For example,
|
|
to match either file <code>foo.c</code> or file <code>bar.c</code>, in ksh you would say
|
|
<code>@(foo|bar).c</code>. The usual zsh way of doing things is <code>(foo|bar).c</code>. To
|
|
turn on the ksh way of doing things, set the option <code>KSH_GLOB</code>; to turn
|
|
off the zsh way, set the options <code>SH_GLOB</code> and <code>NO_BARE_GLOB_QUAL</code>. The
|
|
last of those turns off <strong>qualifiers</strong>, a very powerful way of selecting
|
|
files by type (for example, directories or executable files) instead of
|
|
by name which I'll talk about in <a href="zshguide05.html#subst">chapter 5</a>.</p>
|
|
<p>The other two need a bit more explanation. Try this:</p>
|
|
<pre><code> foo='*'
|
|
print $foo
|
|
</code></pre>
|
|
<p>In zsh, you usually get a `<code>*</code>' printed, while in ksh the `<code>*</code>' is
|
|
expanded to all the files in the directory, just as if you had typed
|
|
`<code>print *</code>'. This is a little like <code>SH_WORD_SPLIT</code>, in that ksh is
|
|
pretending that the value of <code>$foo</code> appears on the command line just as
|
|
if you typed it, while zsh is using what you assigned to <code>foo</code> without
|
|
allowing it to be changed any more. To allow the word to be expanded in
|
|
zsh, too, you can set the option <code>GLOB_SUBST</code>. As with <code>SH_WORD_SPLIT</code>,
|
|
the way around the ksh behaviour if you don't want the value changed is
|
|
to use double quotes: <code>"$foo"</code>.</p>
|
|
<p>You are less likely to have to worry about <code>SH_FILE_EXPANSION</code>. It
|
|
determines when the shell expands things like <code>~/.zshrc</code> to the full
|
|
path, e.g. <code>/home/user2/pws/.zshrc</code>. In the case of zsh, this is usually
|
|
done quite late, after most other forms of expansion such as parameter
|
|
expansion. That means if you set <code>GLOB_SUBST</code> and do</p>
|
|
<pre><code> foo='~/.zshrc'
|
|
print $foo
|
|
</code></pre>
|
|
<p>you would normally see the full path, starting with a `<code>/</code>'. If you
|
|
<em>also</em> set <code>SH_FILE_EXPANSION</code>, however, the `<code>~</code>' is tested much
|
|
earlier, before <code>$foo</code> is replaced when there isn't one yet, so that
|
|
`<code>~/.zshrc</code>' would be printed. This (with both options) is the way ksh
|
|
works. It also means I lied when I said ksh treats <code>$foo</code> exactly as if
|
|
its value had been typed, because if you type <code>print ~/.zshrc</code> the
|
|
`<code>~</code>' does get expanded. So you see how convenient lying is.</p>
|
|
<p><strong><code>NOMATCH</code>, <code>BAD_PATTERN</code></strong></p>
|
|
<p>These also relate to patterns which produce file names, but in this case
|
|
they determine what happens when the pattern doesn't match a file for
|
|
some reason. There are two possible reasons: either no file happened to
|
|
match, or you didn't use a proper pattern. In both cases, zsh, unlike
|
|
ksh, prints an error message. For example,</p>
|
|
<pre><code> % print nosuchfile*
|
|
zsh: no matches found: nosuchfile*
|
|
% print [-
|
|
zsh: bad pattern: [-
|
|
</code></pre>
|
|
<p>(Remember the `<code>%</code>' lines are what you type, with a prompt in front
|
|
which comes from the shell.) You can see there are two different error
|
|
messages: you can stop the first by setting <code>NO_NOMATCH</code>, and the second
|
|
by setting <code>NO_BAD_PATTERN</code>. In both cases, that makes the shell print
|
|
out what you originally type without any expansion when there are no
|
|
matching files.</p>
|
|
<p><strong><code>BG_NICE</code>, <code>NOTIFY</code></strong></p>
|
|
<p>All UNIX shells allow you to start a <em>background</em> job by putting `<code>&</code>'
|
|
at the end of the line; then the shell doesn't wait for the job to
|
|
finish, so you can type something else. In zsh, such jobs are usually
|
|
run at a lower priority (a `higher nice value' in UNIX-speak), so that
|
|
they don't use so much of the processor's time as foreground jobs (all
|
|
the others, without the `<code>&</code>') do. This is so that jobs like editing or
|
|
using the shell don't get slowed down, which can be highly annoying. You
|
|
can turn this feature off by setting <code>NO_BG_NICE</code>.</p>
|
|
<p>When a background job finishes, zsh usually tells you immediately by
|
|
printing a message, which interrupts whatever you're doing. You can stop
|
|
this by setting <code>NO_NOTIFY</code>. Actually, this is an option in most
|
|
versions of ksh, too, but it's a little less annoying in zsh because if
|
|
it happens while you're typing something else to the shell, the shell
|
|
will reprint the line you were on as far as you've got. For example:</p>
|
|
<pre><code> % sleep 3 &
|
|
[1] 40366
|
|
% print The quick brown
|
|
[1] + 40366 done sleep 3
|
|
% print The quick brown
|
|
</code></pre>
|
|
<p>The command sleep simply does nothing for however many seconds you tell
|
|
it, but here it did it in the background (zsh printed a message to tell
|
|
you). After you typed for three seconds, the job exited, and with
|
|
<code>NOTIFY</code> set it printed out another message: the `<code>done</code>' is the key
|
|
thing, as it tells you the job has finished. But zsh was smart enough to
|
|
know the display was messed up, so it reprinted the line you were
|
|
editing, and you can continue. If you were already running another
|
|
programme in the foreground, however, that wouldn't know that zsh had
|
|
printed the message, so the display would still be messed up.</p>
|
|
<p><strong><code>HUP</code></strong></p>
|
|
<p>Signals are the way of persuading a job to do something it doesn't want
|
|
to, such as die; when you type <code>^C</code>, it sends a signal (called <code>SIGINT</code>
|
|
in this case) to the job. In zsh, if you have a background job running
|
|
when the shell exits, the shell will assume you want that to be killed;
|
|
in this case it is sent a particular signal called `<code>SIGHUP</code>' which
|
|
stands for `hangup' (as in telephone, not as in Woody Allen) and is the
|
|
UNIX equivalent of `time to go home'. If you often start jobs that
|
|
should go on even when the shell has exited, then you can set the option
|
|
<code>NO_HUP</code>, and background jobs will be left alone.</p>
|
|
<p><strong><code>KSH_ARRAYS</code></strong></p>
|
|
<p>I've already mentioned this, but here are the details. Suppose you have
|
|
defined an array <code>arr</code>, for example with</p>
|
|
<pre><code> arr=(foo bar)
|
|
</code></pre>
|
|
<p>although the syntax in ksh, which zsh also allows, is</p>
|
|
<pre><code> set -A arr foo bar
|
|
</code></pre>
|
|
<p>In zsh, <code>$arr</code> gives out the whole array; in ksh it just produces the
|
|
first element. In zsh, <code>${arr[1]}</code> refers to the first element of the
|
|
array, i.e. <code>foo</code>, while in ksh the first element is referred to as
|
|
<code>${arr[0]}</code> so that <code>${arr[1]}</code> gives you <code>bar</code>. Finally, in zsh you can
|
|
get away with <code>$arr[1]</code> to refer to an element, while ksh insists on the
|
|
braces. By setting <code>KSH_ARRAYS</code>, zsh will switch to the ksh way of doing
|
|
things. This is one option you need to be particularly careful about
|
|
when writing functions and scripts.</p>
|
|
<p><strong><code>FUNCTION_ARG_ZERO</code></strong></p>
|
|
<p>Shell functions are a useful way of specifying a set of commands to be
|
|
run by the shell. Here's a simple example:</p>
|
|
<pre><code> % fn() { print My name is $0; }
|
|
% fn
|
|
My name is fn
|
|
</code></pre>
|
|
<p>Note the special syntax: the `<code>()</code>' appears after a function name to
|
|
say you are defining one, then a set of commands appears between the
|
|
`<code>{ ... }</code>'. When you type the name of the function, those commands are
|
|
executed. If you know the programming language C, the syntax will be
|
|
pretty familiar, although note that the `<code>()</code>' is a bit of a delusion:
|
|
you might think you would put arguments to the function in there, but
|
|
you can't, it must always appear simply as `<code>()</code>'. If you don't know C,
|
|
it doesn't matter; nothing from C really applies in detail, it's just a
|
|
superficial resemblance.</p>
|
|
<p>In this case, zsh printed the special parameter `<code>$0</code>' (`argument
|
|
zero') and, as you see, that turned into the name of the function. Now
|
|
<code>$0</code> outside a function means the name of the shell, or the name of the
|
|
script for a non-interactive shell, so if you type `<code>print $0</code>' it will
|
|
probably say `<code>zsh</code>'. In most versions of ksh, this is <code>$0</code>'s only use;
|
|
it doesn't change in functions, and `fn' would print `ksh'. To get
|
|
this behaviour, you can set <code>NO_FUNCTION_ARG_ZERO</code>. There's probably no
|
|
reason why you would want to, but zsh functions quite often test their
|
|
own name, so this is one reason why they might not work.</p>
|
|
<p>There's another difference when defining functions, irrespective of
|
|
<code>FUNCTION_ARG_ZERO</code>: in zsh, you can get away without the final `<code>;</code>'
|
|
before the end of the definition of <code>fn</code>, because it knows the `<code>}</code>'
|
|
must finish the last command as well as the function; but ksh is not so
|
|
forgiving here. Lots of syntactic know-alls will probably be able to
|
|
tell you why that's a good thing, but fortunately I can't.</p>
|
|
<p><strong><code>KSH_AUTOLOAD</code></strong></p>
|
|
<p>There's an easy way of loading functions built into both ksh and zsh.
|
|
Instead of putting them all together in a big startup file, you can put
|
|
a single line in that,</p>
|
|
<pre><code> autoload fn
|
|
</code></pre>
|
|
<p>and the function `<code>fn</code>' will only be loaded when you run it by typing
|
|
its name as a command. The shell needs to know where the function is
|
|
stored. This is done by a special parameter called <code>$fpath</code>, an array
|
|
which is a list of directories; it will search all the directories for a
|
|
file called <code>fn</code>, and use that as the function definition. If you want
|
|
to try this you can type `<code>autoload fn; fpath=(. $fpath)</code>' and write a
|
|
file called <code>fn</code> in the current directory.</p>
|
|
<p>Unfortunately ksh and zsh disagree a bit about what should be in that
|
|
file. The normal zsh way of doing things is just putting the body of the
|
|
function there. So if the file <code>fn</code> is autoloadable and contains,</p>
|
|
<pre><code> # this is a simple function
|
|
print My name is $0
|
|
</code></pre>
|
|
<p>then typing `<code>fn</code>' will have exactly the same effect as the function
|
|
<code>fn</code> above, printing `<code>My name is fn</code>'. Zsh users tend to like this
|
|
because the function is written the same way as a script; if instead you
|
|
had typed <code>zsh fn</code>, to call the file as a script with a new copy of zsh
|
|
of its own, it would have worked the same way. The first line is a
|
|
comment; it's ignored, and in zsh not even autoloaded when the function
|
|
is run, so it's not only much clearer to add explanatory contents, it
|
|
also doesn't use any more memory either. It uses more disk space, of
|
|
course, but nowadays even home PCs come with the sort of disk size which
|
|
allows you a little indulgence with legibility.</p>
|
|
<p>However, ksh does things differently, and here the file <code>fn</code> needs to
|
|
contain</p>
|
|
<pre><code> fn() {
|
|
# this is a simple function
|
|
print My name is $0
|
|
}
|
|
</code></pre>
|
|
<p>in other words, exactly what you would type to define the function. The
|
|
advantage of this form is that you can put other things in the file,
|
|
which will then be run straight away and forgotten about, such as
|
|
defining things that <code>fn</code> may need to use but which don't need to be
|
|
redefined every single time you run <code>fn</code>. The option to force zsh to
|
|
work the ksh way here is called <code>KSH_AUTOLOAD</code>. (If you wanted to try
|
|
the second example, you would need to type `<code>unfunction fn; autoload fn</code>' to remove the function from memory and mark it for autoloading
|
|
again.)</p>
|
|
<p>Actually, zsh is a little bit cleverer. If the option <code>KSH_AUTOLOAD</code> is
|
|
not set, but the file contains just a function definition in the ksh
|
|
form and nothing else (like the last one above, in fact), then zsh
|
|
assumes that it needs to run the function just loaded straight away. The
|
|
other possibility would be that you wanted to define a function which
|
|
did nothing other than define a function of the same name, which is
|
|
assumed to be unlikely --- and if you really want to do that, you will
|
|
need to trick zsh by putting a do-nothing command in the same file, such
|
|
as a `<code>:</code>' on the last line.</p>
|
|
<p>A final complication --- sorry, but this one actually happens --- is
|
|
that sometimes in zsh you want to define not just the function to be
|
|
called, but some others to help it along. Then you need to do this:</p>
|
|
<pre><code> fn() {
|
|
# this is the function after which the file is named
|
|
}
|
|
helper() {
|
|
# goodness knows what this does
|
|
}
|
|
fn "$@"
|
|
# this actually calls the function the first time,
|
|
# with any arguments passed (see the subsection
|
|
# `Function Parameters' in the section `Functions'
|
|
# of the next chapter for the "$@").
|
|
</code></pre>
|
|
<p>That last non-comment line is unnecessary with <code>KSH_AUTOLOAD</code>. The
|
|
functions supplied with zsh assume that <code>KSH_AUTOLOAD</code> is not set,
|
|
however, so you shouldn't turn it on unless you need to. You could just
|
|
make <code>fn</code> into the whole body, as usual, and define <code>helper</code> inside
|
|
that; the problem is that <code>helper</code> would be redefined each time you
|
|
executed <code>fn</code>, which is inefficient. A better way of avoiding the
|
|
problem would be to define helper as a completely separate function,
|
|
itself autoloaded: in both zsh and ksh, it makes no difference whether a
|
|
function is defined inside another function or outside it, unlike (say)
|
|
Pascal or Scheme.</p>
|
|
<p><strong><code>LOCAL_OPTIONS</code>, <code>LOCAL_TRAPS</code></strong></p>
|
|
<p>These two options also refer to functions, and here the ksh way of doing
|
|
things is usually preferable, so many people set at least
|
|
<code>LOCAL_OPTIONS</code> in a lot of their functions. The first versions of zsh
|
|
didn't have these, which is why you need to turn them on by hand.</p>
|
|
<p>If <code>LOCAL_OPTIONS</code> is set in a function (or was already set before the
|
|
function, and not unset inside it), then any options which are changed
|
|
inside the function will be put back the way they were when the function
|
|
finishes. So</p>
|
|
<pre><code> fn() {
|
|
setopt localoptions kshglob
|
|
...
|
|
}
|
|
</code></pre>
|
|
<p>allows you to use a function with the ksh globbing syntax, but will make
|
|
sure that the option <code>KSH_GLOB</code> is restored to whatever it was before
|
|
when the function exits. This works even if the function was interrupted
|
|
by typing <code>^C</code>. Note that <code>LOCAL_OPTIONS</code> will itself be restored to the
|
|
way it was.</p>
|
|
<p>The option <code>LOCAL_TRAPS</code>, which first appeared in version 3.1.6, is for
|
|
a similar reason but refers to (guess what) <strong>traps</strong>, which are a way
|
|
of stopping signals sent to the shell, for example by typing <code>^C</code> to
|
|
cancel something (<code>SIGINT</code>, short for `signal interrupt'), or <code>^Z</code> to
|
|
suspend it temporarily (<code>SIGTSTP</code>, `signal terminal stop'), or <code>SIGHUP</code>
|
|
which we've already met, and so on. To do something of your own when the
|
|
shell gets a <code>^C</code>, you can do</p>
|
|
<pre><code> trap 'print I caught a SIGINT' INT
|
|
</code></pre>
|
|
<p>and the set of commands in quotes will be run when the <code>^C</code> arrives (you
|
|
can even try it without running anything). If the string is empty (just
|
|
<code>'``'</code> with nothing inside), the signal will be ignored; typing <code>^C</code> has
|
|
no effect. To put it back to normal, the command is `<code>trap - INT</code>'.</p>
|
|
<p>Traps are most useful in functions, where you may temporarily (say) not
|
|
want things to stop when you hit <code>^C</code>, or you may want to clear up
|
|
something before returning from the function. So now you can guess what
|
|
<code>LOCAL_TRAPS</code> does; with</p>
|
|
<pre><code> fn() {
|
|
setopt localoptions localtraps
|
|
trap '' INT
|
|
...
|
|
}
|
|
</code></pre>
|
|
<p>the shell will ignore <code>^C</code>'s to the end of the function, but then put
|
|
back the trap that was there before, or remove it completely if there
|
|
was none. Traps are described in more detail in <a href="zshguide03.html#syntax">chapter
|
|
3</a>.</p>
|
|
<p>There is a very convenient shorthand for making options and traps local,
|
|
as well as for setting the others to their standard values: put
|
|
`<code>emulate -L zsh</code>' at the start of a function. This sets the option
|
|
values back to the ones set when zsh starts, but with <code>LOCAL_OPTIONS</code>
|
|
and <code>LOCAL_TRAPS</code> set too, so you now know exactly how things are going
|
|
to work for the rest of the function, whatever options are set in the
|
|
outside world. In fact, this only changes the options which affect
|
|
normal programming; you can set every option which it makes sense to set
|
|
to its standard value with `<code>emulate -RL zsh</code>' (it doesn't, for
|
|
example, make sense to change options like <code>login</code> at this point).
|
|
Furthermore, you can make the shell behave as much like ksh as it knows
|
|
how to by doing `<code>emulate -L ksh</code>', with or without the <code>-R</code>.</p>
|
|
<p>The <code>-L</code> option to <code>emulate</code> actually only appears in versions from
|
|
3.0.6 and 3.1.6. Before that you needed</p>
|
|
<pre><code> emulate zsh
|
|
setopt localoptions
|
|
</code></pre>
|
|
<p>since <code>localtraps</code> didn't exist, and indeed doesn't exist in 3.0.6
|
|
either.</p>
|
|
<p><strong><code>PROMPT_PERCENT</code>, <code>PROMPT_SUBST</code></strong></p>
|
|
<p>As promised, setting prompts will be discussed later, but for now there
|
|
are two ways of getting information into prompts, such as the parameter
|
|
<code>$PS1</code> which determines the usual prompt at the start of a new command
|
|
line. One is by using <em>percent escapes</em>, which means a `<code>%</code>' followed
|
|
by another character, maybe with a number between the two. For example,
|
|
the default zsh prompt is `<code>%m%# </code>'. The first percent escape turns
|
|
into the name of the host computer, the second usually turns into a
|
|
`<code>%</code>', but a `<code>#</code>' for the superuser. However, ksh doesn't have these,
|
|
so you can turn them off by setting <code>NO_PROMPT_PERCENT</code>.</p>
|
|
<p>The usual ksh way of doing things, on the other hand, is by putting
|
|
parameters in the prompt to be substituted. To get zsh to do this, you
|
|
have to set <code>PROMPT_SUBST</code>. Then assigning</p>
|
|
<pre><code> PS1='${PWD}% '
|
|
</code></pre>
|
|
<p>is another way of putting the name of the current directory (`<code>$PWD</code>'
|
|
is presumably named after the command `pwd' to `print working
|
|
directory') into the prompt. Note the single quotes, so that this
|
|
happens when the prompt is shown, not when it is assigned. If they
|
|
weren't there, or were double quotes, then the <code>$PWD</code> would be expanded
|
|
to the directory when the assignment took place, probably your home
|
|
directory, and wouldn't change to reflect the directory you were
|
|
actually in. Of course, you need the quotes for the space, too, else it
|
|
just gets swallowed up when the assignment is executed.</p>
|
|
<p>As there is potentially much more information available in parameters
|
|
than the fixed number of predefined percent escapes, you may wish to set
|
|
<code>PROMPT_SUBST</code> anyway. Furthermore, you can get the output of commands
|
|
into prompts since other forms of expansion are done on them, not just
|
|
that of parameters; in fact, prompts with <code>PROMPT_SUBST</code> are expanded
|
|
pretty much the same as a string inside double quotes every time the
|
|
prompt is displayed.</p>
|
|
<p><strong><code>RM_STAR_SILENT</code></strong></p>
|
|
<p>Everybody at some time or another deletes more files than they mean to
|
|
(and <em>that's</em> a gross understatement); my favourite is:</p>
|
|
<pre><code> rm *>o
|
|
</code></pre>
|
|
<p>That `<code>></code>' should be a `.', but I still had the shift key pressed.
|
|
This removes all files, echoing the output (there isn't any) into a file
|
|
`o'. Delightfully, the empty file `o' is not removed. (Don't try this
|
|
at home.)</p>
|
|
<p>There is a protection mechanism built into zsh to stop you deleting all
|
|
the files in a directory by accident. If zsh finds that the command is
|
|
`<code>rm</code>', and there is a `<code>*</code>' on the command line (there may be other
|
|
stuff as well), then it will ask you if you really want to delete all
|
|
those files. You can turn this off by setting <code>RM_STAR_SILENT</code>.
|
|
Overreliance on this option is a bad idea; it's only a last line of
|
|
defence.</p>
|
|
<p><strong><code>SH_OPTION_LETTERS</code></strong></p>
|
|
<p>Many options also have single letters to stand for them; you can set an
|
|
option in this way by, for example, `<code>set -f</code>', which sets <code>NO_RCS</code>.
|
|
However, even where sh, ksh and zsh share options, not all have the same
|
|
letters. This option allows the single letter options to be more like
|
|
those in sh and ksh. Look them up in the manual if you want to know, but
|
|
I already recommended that you use the full names for options anyway.</p>
|
|
<p><strong><code>SH_WORD_SPLIT</code></strong></p>
|
|
<p>I've already talked about this, see above, but it's mentioned here so
|
|
you don't forget it, since it's an important difference.</p>
|
|
<p><strong>Starting zsh as ksh</strong></p>
|
|
<p>Finally on the subject of compatibility, you might like to know that as
|
|
well as `<code>emulate</code>' there is another way of forcing zsh to behave as
|
|
much like sh or ksh as possible. This is by actually calling zsh under
|
|
the name ksh. You don't need to rename zsh, you can make a link from the
|
|
name zsh to the name ksh, which will be enough to convince it.</p>
|
|
<p>There is an easier way when you are doing this from within zsh itself.
|
|
The parameter <code>$ARGV0</code> is special; it is the value which will be passed
|
|
as the first argument of a command which is run by the shell. Normally
|
|
this is the name of the command, but it doesn't have to be since the
|
|
command only finds out what it is after it has already been run. You can
|
|
use it to trick a programme into thinking its name is different. So</p>
|
|
<pre><code> ARGV0=ksh zsh
|
|
</code></pre>
|
|
<p>will start a copy of zsh that tries to make itself like ksh. Note this
|
|
doesn't work unless you're already in zsh, as the <code>$ARGV0</code> won't be
|
|
special.</p>
|
|
<p>I haven't mentioned putting a parameter assignment before a command
|
|
name, but that simply assigns the parameter (strictly an environment
|
|
variable in this case) for the duration of the command; the value
|
|
<code>$ARGV0</code> won't be set after that command (the ksh-like zsh) finishes, as
|
|
you can easily test with <code>print</code>. While I'm here, I should mention a few
|
|
of its other features. First, the parameter is automatically exported to
|
|
the environment, meaning it's available for other programmes started by
|
|
zsh (including, in this case, the new zsh) --- see the section on
|
|
environment variables below. Second, this doesn't do what you might
|
|
expect:</p>
|
|
<pre><code> FOO=bar print $FOO
|
|
</code></pre>
|
|
<p>because of the order of expansion: the command line and its parameters
|
|
are expanded before execution, giving whatever value <code>$FOO</code> had before,
|
|
probably none, then FOO=bar is put into the environment, and then the
|
|
command is executed but doesn't use the new value of <code>$FOO</code>.</p>
|
|
<p><span id="l15"></span></p>
|
|
<h3 id="252-options-for-csh-junkies"><a class="header" href="#252-options-for-csh-junkies">2.5.2: Options for csh junkies</a></h3>
|
|
<p>As well as old ksh users, there are some options available to make old
|
|
csh and tcsh users feel more at home. As you will already have noticed,
|
|
the syntax is very different, so you are never going to feel completely
|
|
at home and it might be best just to remember the fact. But here is a
|
|
brief list. The last, <code>CSH_NULL_GLOB</code>, is actually quite useful.</p>
|
|
<p><strong><code>CSH_JUNKIE_HISTORY</code></strong></p>
|
|
<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><strong><code>CSH_JUNKIE_LOOPS</code></strong></p>
|
|
<p>Normal zsh loops look something like this,</p>
|
|
<pre><code> while true; do
|
|
print Never-ending story
|
|
done
|
|
</code></pre>
|
|
<p>which just prints the message over and over (type it line-by-line at the
|
|
prompt, if you like, then <code>^C</code> to stop it). With <code>CSH_JUNKIE_LOOPS</code> set,
|
|
you can instead do</p>
|
|
<pre><code> while true
|
|
print Never-ending story
|
|
end
|
|
</code></pre>
|
|
<p>which will, of course, make your zsh code unlike most other people's, so
|
|
for most users it's best to learn the proper syntax.</p>
|
|
<p><strong><code>CSH_NULL_GLOB</code></strong></p>
|
|
<p>This is another of the family of options like <code>NO_NOMATCH</code>, already
|
|
mentioned. In this case, if you have a command line consisting of a set
|
|
of patterns, at least one of them must match at least one file, or an
|
|
error is caused; any that don't match are removed from the command line.
|
|
The default is that all of them have to match. There is one final member
|
|
of this set of options, <code>NULL_GLOB</code>: all non-matching patterns are
|
|
removed from the command line, no error is caused. As a summary, suppose
|
|
you enter the command `<code>print file1* file2*</code>' and the directory
|
|
contains just the file <code>file1.c</code>.</p>
|
|
<ol>
|
|
<li>By default, there must be files matching both patterns, so an error
|
|
is reported.</li>
|
|
<li>With <code>NO_NOMATCH</code> set, any patterns which don't match are left
|
|
alone, so `<code>file1.c file2*</code>' is printed.</li>
|
|
<li>With <code>CSH_NULL_GLOB</code> set, <code>file1*</code> matched, so <code>file2*</code> is silently
|
|
removed; `<code>file1.c</code>' is reported. If that had not been there, an
|
|
error would have been reported.</li>
|
|
<li>With <code>NULL_GLOB</code> set, any patterns which don't match are removed, so
|
|
again `<code>file1.c</code>' is printed, but in this case if that had not been
|
|
there a blank line would have been printed, with no error.</li>
|
|
</ol>
|
|
<p><code>CSH_NULL_GLOB</code> is good thing to have set since it can keep you on the
|
|
straight and narrow without too many unwanted error messages, so this
|
|
time it's not just for csh junkies.</p>
|
|
<p><strong><code>CSH_JUNKIE_QUOTES</code></strong></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><span id="l16"></span></p>
|
|
<h3 id="253-the-history-mechanism-types-of-history"><a class="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 <a href="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><span id="l17"></span></p>
|
|
<h3 id="254-setting-up-history"><a class="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><span id="l18"></span></p>
|
|
<h3 id="255-history-options"><a class="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
|
|
<code>INC_APPEND_HISTORY</code>, <code>SHARE_HISTORY</code>, <code>HIST_EXPIRE_DUPS_FIRST</code>,
|
|
<code>HIST_IGNORE_ALL_DUPS</code>, <code>HIST_SAVE_NO_DUPS</code> and <code>HIST_NO_FUNCTIONS</code>. I
|
|
have already described <code>BANG_HIST</code>, <code>CSH_JUNKIE_HISTORY</code> and
|
|
<code>HIST_VERIFY</code> and I won't talk about them again.</p>
|
|
<p><strong><code>APPEND_HISTORY</code>, <code>INC_APPEND_HISTORY</code>, <code>SHARE_HISTORY</code></strong></p>
|
|
<p>Normally, when it writes a history file, zsh just overwrites everything
|
|
that's there. <code>APPEND_HISTORY</code> allows it to append the new history to
|
|
the old. The shell will make an effort not to write out lines which
|
|
should be there already; this can get complicated if you have lots of
|
|
zshs running in different windows at once. This option is a good one for
|
|
most people to use. <code>INC_APPEND_HISTORY</code> means that instead of doing
|
|
this when the shell exits, each line is added to the history in this way
|
|
as it is executed; this means, for example, that if you start up a zsh
|
|
inside the main shell its history will look like that of the main shell,
|
|
which is quite useful. It also means the ordering of commands from
|
|
different shells running at the same time is much more logical ---
|
|
basically just the order they were executed --- so for 3.1.6 and higher
|
|
this option is recommended.</p>
|
|
<p><code>SHARE_HISTORY</code> takes this one stage further: as each line is added, the
|
|
history file is checked to see if anything was written out by another
|
|
shell, and if so it is included in the history of the current shell too.
|
|
This means that zsh's running in different windows but on the same host
|
|
(or more generally with the same home directory) share the same history.
|
|
Note that zsh tries not to confuse you by having unexpected history
|
|
entries pop up: if you use <code>!</code>-style history, the commands from other
|
|
session don't appear in the history list until you explicitly type the
|
|
<code>history</code> command to display them, so that you can be sure what command
|
|
you are actually reexecuting. The Korn shell always behaves as if
|
|
<code>SHARE_HISTORY</code> is set, presumably because it doesn't store history
|
|
internally.</p>
|
|
<p><strong><code>EXTENDED_HISTORY</code></strong></p>
|
|
<p>This makes the format of the history entry more complicated: in addition
|
|
to just the command, it saves the time when the command was started and
|
|
how long it ran for. The <code>history</code> command takes three options which use
|
|
this: <code>history -d</code> prints the start time of the command; <code>history -f</code>
|
|
prints that as well as the date; <code>history -D</code> (which you can combine
|
|
with <code>-f</code> or <code>-d</code>) prints the command's elapsed time. The date format
|
|
can be changed with <code>-E</code> for European (<em>day</em>.<em>month</em>.<em>year</em>) and <code>-i</code>
|
|
for international (<em>year</em>-<em>month</em>-<em>day</em>) formats. The main reasons why
|
|
you <em>wouldn't</em> want to set this would be shortage of disk space, or
|
|
because you wanted your history file to be read by another shell.</p>
|
|
<p><strong><code>HIST_IGNORE_DUPS</code>, <code>HIST_IGNORE_ALL_DUPS</code>, <code>HIST_EXPIRE_DUPS_FIRST</code>,
|
|
<code>HIST_SAVE_NO_DUPS</code>, <code>HIST_FIND_NO_DUPS</code></strong></p>
|
|
<p>These options give ways of dealing with the duplicate lines that often
|
|
appear in the history. The simplest is <code>HIST_IGNORE_DUPS</code>, which tells
|
|
the shell not to store a history line if it's the same as the previous
|
|
one, thus collapsing a lot of repeated commands down to one; this is a
|
|
very good option to have set. It does nothing when duplicate lines are
|
|
not adjacent, so for example alternating pairs of commands will always
|
|
be stored. The next two options can help here: <code>HIST_IGNORE_ALL_DUPS</code>
|
|
simply removes copies of lines still in the history list, keeping the
|
|
newly added one, while <code>HIST_EXPIRE_DUPS_FIRST</code> is more subtle: it
|
|
preferentially removes duplicates when the history fills up, but does
|
|
nothing until then. <code>HIST_SAVE_NO_DUPS</code> means that whatever options are
|
|
set for the current session, the shell is not to save duplicated lines
|
|
more than once; and <code>HIST_FIND_NO_DUPS</code> means that even if duplicate
|
|
lines have been saved, searches backwards with editor commands don't
|
|
show them more than once.</p>
|
|
<p><strong><code>HIST_ALLOW_CLOBBER</code>, <code>HIST_REDUCE_BLANKS</code></strong></p>
|
|
<p>These allow the history mechanism to make changes to lines as they are
|
|
entered. The first affects output redirections, where you use the symbol
|
|
<code>></code> to redirect the output of a command or set of commands to a named
|
|
file, or use <code>>``></code> to append the output to that file. If you have the
|
|
<code>NO_CLOBBER</code> option set, then</p>
|
|
<pre><code> touch newfile
|
|
echo hello >newfile
|
|
</code></pre>
|
|
<p>fails, because the `<code>touch</code>' command has created <code>newfile</code> and
|
|
<code>NO_CLOBBER</code> won't let you overwrite (clobber) it in the next line. With
|
|
<code>HIST_ALLOW_CLOBBER</code>, the second line appears in the history as</p>
|
|
<pre><code> echo hello >|newfile
|
|
</code></pre>
|
|
<p>where the <code>>|</code> overrides <code>NO_CLOBBER</code>. So to get round the <code>NO_CLOBBER</code>
|
|
you can just go back to the previous line and execute it without editing
|
|
it.</p>
|
|
<p>The second option, <code>HIST_REDUCE_BLANKS</code>, will tidy up the line when it
|
|
is entered into the history by removing any excess blanks that mean
|
|
nothing to the shell. This can also mean that the line becomes a
|
|
duplicate of a previous one even if it would not have been in its
|
|
untidied form. It is smart enough not to remove blanks which are
|
|
important, i.e. are quoted.</p>
|
|
<p><strong><code>HIST_IGNORE_SPACE</code>, <code>HIST_NO_STORE</code>, <code>HIST_NO_FUNCTIONS</code></strong></p>
|
|
<p>These three options allow you to say that certain lines shouldn't go
|
|
into the history at all. <code>HIST_IGNORE_SPACE</code> means that lines which
|
|
begin with a space don't go into the history; the idea is that you
|
|
deliberately type a space, which is not otherwise significant to the
|
|
shell, before entering any line you want to be forgotten immediately
|
|
afterwards. In zsh 4.0.1 this is implemented so that you can always
|
|
recall the immediately preceding line for editing, even if it had a
|
|
space; but when the next line is executed and entered into the history,
|
|
the line beginning with the space is forgotten.</p>
|
|
<p><code>HIST_NO_STORE</code> tells the shell not to store <code>history</code> or <code>fc</code> commands.
|
|
while <code>HIST_NO_FUNCTIONS</code> tells it not to store function definitions as
|
|
these, though usually infrequent, can be tiresomely long. A function
|
|
definition is anything beginning `<code>function funcname {...</code>' or
|
|
`<code>funcname () { ...</code>'.</p>
|
|
<p><strong><code>NO_HIST_BEEP</code></strong></p>
|
|
<p>Finally, <code>HIST_BEEP</code> is used in the editor: if you try to scroll up or
|
|
down beyond the end of the history list, the shell will beep. It is on
|
|
by default, so use <code>NO_HIST_BEEP</code> to turn it off.</p>
|
|
<p><span id="l19"></span></p>
|
|
<h3 id="256-prompts"><a class="header" href="#256-prompts">2.5.6: Prompts</a></h3>
|
|
<p>Most people have some definitions in <code>.zshrc</code> for altering the prompt
|
|
you see at the start of each line. I've already mentioned
|
|
<code>PROMPT_PERCENT</code> (set by default) and <code>PROMPT_SUBST</code> (unset by default);
|
|
I'll assume here you haven't changed these settings, and point out some
|
|
of the possibilities with <strong>prompt escapes</strong>, sequences that start with
|
|
a `<code>%</code>'. If you get really sophisticated, you might need to turn on
|
|
<code>PROMPT_SUBST</code>.</p>
|
|
<p>The main prompt is in a parameter called either <code>$PS1</code> or <code>$PROMPT</code> or
|
|
<code>$prompt</code>; the reason for having all these names is historical --- they
|
|
come from different shells --- so I'll just stick with the shortest.
|
|
There is also <code>$RPS1</code>, which prints a prompt at the right of the screen.
|
|
The point of this is that it automatically disappears if you type so far
|
|
along the line that you run into it, so it can help make the best use of
|
|
space for showing long things like directories.</p>
|
|
<p><code>$PS2</code> is shown when the shell is waiting for some more input, i.e. it
|
|
knows that what you have typed so far isn't a complete line: it may
|
|
contain the start of a quoted expression, but not the end, or the start
|
|
of some syntactic structure which is not yet finished. Usually you will
|
|
keep it different from <code>$PS1</code>, but all the same escapes are understood
|
|
in all five prompts.</p>
|
|
<p><code>$PS3</code> is shown within a loop started by the shell's <code>select</code> mechanism,
|
|
when the shell wants you to input a choice: see the <code>zshmisc</code> manual
|
|
page as I won't say much about that.</p>
|
|
<p><code>$PS4</code> is useful in debugging: there is an option <code>XTRACE</code> which causes
|
|
the shell to print out lines about to be executed, preceded by <code>$PS4</code>.
|
|
Only from version 3.1.6 has it started to be substituted in the same way
|
|
as the other prompts, though this turns out to be very useful --- see
|
|
`Location in script or function' in the following list.</p>
|
|
<p>Here are some of the things you might want to include in your prompts.
|
|
Note that you can try this out before you alter the prompt by using
|
|
`<code>print -P</code>': this expands strings just are as they are in prompts. You
|
|
will probably need to put the string in single quotes.</p>
|
|
<p><strong>The time</strong></p>
|
|
<p>Zsh allows you lots of different ways of putting the time into your
|
|
prompt with percent escapes. The simplest are <code>%t</code> and <code>%T</code>, the time in
|
|
12 and 24 hour formats, and <code>%*</code>, the same as <code>%T</code> but with seconds; you
|
|
can also have the date as (e.g.) `<code>Wed 22</code>' using <code>%w</code>, as `<code>9/22/99</code>'
|
|
(US format) using %W, or as `<code>99-09-22</code>' (International format) using
|
|
%D. However, there is another way of using %D to get many more
|
|
possibilities: a following string in braces, `<code>%D{...}</code>' can contain a
|
|
completely different set of percent escapes all of which refer to
|
|
elements of the time and date. On most systems, the documentation for
|
|
the <code>strftime</code> function will tell you what these are. zsh has a few of
|
|
its own, given in the <code>zshmisc</code> manual page in the <code>PROMPT EXPANSION</code>
|
|
section. For example, I use <code>%D{%L:%M}</code> which gives the time in hours
|
|
and minutes, with the hours as a single digit for 1 to 9; it looks more
|
|
homely to my unsophisticated eyes.</p>
|
|
<p>You can have more fun by using the `<code>%</code>(<em>numX</em>.<em>true</em>.<em>false</em>)' syntax,
|
|
where <em>X</em> is one of <code>t</code> or <code>T</code>. For <code>t</code>, if the time in minutes is the
|
|
same as <em>num</em> (default zero), then <em>true</em> is used as the text for this
|
|
section of the prompt, while <em>false</em> is used otherwise. <code>T</code> does the
|
|
same for hours. Hence</p>
|
|
<pre><code> PS1='%(t.Ding!.%D{%L:%M})%# '
|
|
</code></pre>
|
|
<p>prints the message `<code>Ding!</code>' at zero minutes past the hour, and a more
|
|
conventional time otherwise. The `<code>%#</code>' is the standard sequence which
|
|
prints a `<code>#</code>' if you are the superuser (root), or a `<code>%</code>' for
|
|
everyone else, which occurs in a lot of people's prompts. Likewise, you
|
|
could use `<code>%</code>(<code>30t.Dong!.</code>...' for a message at half past the hour.</p>
|
|
<p><strong>The current directory</strong></p>
|
|
<p>The sequence `<code>%~</code>' prints out the directory, with any home or named
|
|
directories (see below) shortened to the form starting with <code>~</code>; the
|
|
sequence `<code>%/</code>' doesn't do that shortening, so usually `<code>%~</code>' is
|
|
better. Directories can be long, and there are various ways to deal with
|
|
it. First, if you are using a windowing system you can put the directory
|
|
in the title bar, rather than anywhere inside the window. Second, you
|
|
can use <code>$RPS1</code> which disappears when you type near it. Third, you can
|
|
pick segments out of `<code>%~</code>' or `<code>%/</code>' by giving them a number after
|
|
the `<code>%</code>': for example, `<code>%1~</code>' just picks out the last segment of the
|
|
path to the current directory.</p>
|
|
<p>The fourth way gives you the most control. Prompts or parts of prompts,
|
|
not just bits showing the directory, can be truncated to any length you
|
|
choose. To truncate a path on the left, use something like
|
|
`<code>%10<</code><em>...</em><code><%~</code>'. That works like this: the `<code>%<``<</code>' is the basic
|
|
form for truncation. The 10 after the `<code>%</code>' says that anything
|
|
following is limited to 10 characters, and the characters `<em>...</em>' are
|
|
to be displayed whenever the prompt would otherwise be longer than that
|
|
(you can leave this empty). This applies to anything following, so now
|
|
the <code>%~</code> can't be longer than 10 characters, otherwise it will be
|
|
truncated (to 7 characters, once the `<code>...</code>' has been printed). You can
|
|
turn off truncation with `<code>%<``<</code>', i.e. no number after the `<code>%</code>';
|
|
truncation then applies to the entire region between where it was turned
|
|
on and where it was turned off (this has changed from older versions of
|
|
zsh, where it just applied to individual `<code>%</code>' constructs).</p>
|
|
<p><strong>What are you waiting for?</strong></p>
|
|
<p>The prompt <code>$PS2</code> appears when the shell is waiting for you to finish
|
|
entering something, and it's useful to know what the shell is waiting
|
|
for. The sequence `<code>%_</code>' shows this. It's part of the default <code>$PS2</code>,
|
|
which is `<code>%_> </code>'. Hence, if you type `<code>if true; then</code>' and <code><RET></code>,
|
|
the prompt will say `<code>then> </code>'. You can also use it in the trace
|
|
prompt, <code>$PS4</code>, to show the same information about what is being
|
|
executed in a script or function, though as there is usually enough
|
|
information there (as described next) it's not part of the default. In
|
|
this case, a number after the `<code>%</code>' will limit the depth shown, so with
|
|
`<code>%1_</code>' only the most recent thing will be mentioned.</p>
|
|
<p><strong>Location in script or function</strong></p>
|
|
<p>The default <code>$PS4</code> contains `<code>%N</code>' and `<code>%i</code>', which tell you the name
|
|
of the most recently started function, script, or sourced file, and the
|
|
line number being executed inside it; they are not very useful in other
|
|
prompts. However, `<code>%i</code>' in <code>$PS1</code> will tell you the current
|
|
interactive line number, which zsh keeps track of, though doesn't
|
|
usually show you; the parameter <code>$LINENO</code> contains the same information.</p>
|
|
<p>Another point to bear about `<code>%i</code>' in mind is that the line number
|
|
shown applies to the version of a function first read in, not how it
|
|
appears with the `<code>functions</code>' command, which is tidied up. If you use
|
|
autoloaded functions, however, the file containing the function will
|
|
usually be what you want to alter, so this shouldn't be a problem when
|
|
debugging.</p>
|
|
<p>Remember, the <code>$PS4</code> display only happens when the <code>XTRACE</code> option is
|
|
set; as options may be local to functions, and always are to scripts,
|
|
you will often need to put an explicit `<code>setopt xtrace</code>' at the top of
|
|
whatever you are debugging. Alternatively, you can use `<code>typeset -ft</code>
|
|
<em>funcname</em>' to turn on tracing for that function (something I only just
|
|
discovered); use `<code>typeset +ft</code> <em>funcname</em>' to turn it off again.</p>
|
|
<p><strong>Other bits and pieces</strong></p>
|
|
<p>There are many other percent escapes described in the <code>zshmisc</code> manual
|
|
page, mostly straightforward. For example, `<code>%h</code>' shows you the history
|
|
entry number, useful if you are using bang-history; `<code>%m</code>' shows you
|
|
the current host name up to any dot; `<code>%n</code>' shows the username.</p>
|
|
<p>There are two other features I happen to use myself. First, it's
|
|
sometimes convenient to know when the last command failed. Every command
|
|
returns a status, which is a number: zero for success, some other number
|
|
for some type of failure. You can get this from the parameter `<code>$?</code>' or
|
|
`<code>$status</code>' (again, they refer to the same thing). It's also available
|
|
in the prompt as `<code>%?</code>', and there's also one of the so-called
|
|
`ternary' expressions with parentheses I described for time, which pick
|
|
different strings depending on a test. Here the test is, reasonably
|
|
enough, `<code>%</code>(<code>?...</code>'. Putting these two together, you can get a message
|
|
which is only displayed when the exit status is non-zero; I've put an
|
|
extra set of parentheses around the number just to make it clearer,
|
|
where the `)' needs to be turned into `<code>%</code>)' to stop it marking the
|
|
end of the group:</p>
|
|
<pre><code> PS1='%(?..(%?%))%# '
|
|
</code></pre>
|
|
<p>It's also sometimes convenient to know if you're in a subshell, that is
|
|
if you've started another shell within the main one by typing `<code>zsh</code>'.
|
|
You can do this by using another ternary expression:</p>
|
|
<pre><code> PS1='%(2L.+.)%# '
|
|
</code></pre>
|
|
<p>This checks the parameter <code>SHLVL</code>, which is incremented every time a new
|
|
zsh starts, so if there was already one running (which would have set
|
|
<code>SHLVL</code> to 1), it will now be 2; and if <code>SHLVL</code> is at least 2, an extra
|
|
`<code>+</code>' is printed in front of the prompt, otherwise nothing. If you're
|
|
using a windowing system, you may need to turn the 2 into 3 as there may
|
|
be a zsh already running when you first log in, so that the shells in
|
|
the windows have <code>SHLVL</code> set to 2 already. This depends a good deal on
|
|
how your windowing system is set up; finding out more is left as an
|
|
exercise for the reader.</p>
|
|
<p><strong>Colours</strong></p>
|
|
<p>Many terminals can now display colours, and it is quite useful to be
|
|
able to put these into prompts to distinguish those from the surrounding
|
|
text. I often find a programme has just dumped a whole load of output on
|
|
my terminal and it's not obvious where it starts. Being able to find the
|
|
prompt just before helps a lot.</p>
|
|
<p>Colors, like bold or underlined text, use escape sequences which don't
|
|
move the cursor. The golden rule for inserting any such escape sequences
|
|
into prompts is to surround them with `<code>%{</code>' at the start and `<code>%}</code>'
|
|
at the end. Otherwise, the shell will be confused about the length of
|
|
the line. This affects what happens when the line editor needs to redraw
|
|
the line, and also changes the position of the right prompt <code>$RPS1</code>, if
|
|
you use that. You don't need that with the special sequences <code>%B</code> and
|
|
<code>%b</code>, which start and stop bold text, because the shell already knows
|
|
what to do with those; it's only random characters which you happen to
|
|
know don't move the cursor, though the shell doesn't, that cause the
|
|
problem.</p>
|
|
<p>In the case of colours, there is a shell function <code>colors</code> supplied with
|
|
the standard distribution to help you. When loaded and run, it defines
|
|
associative array parameters <code>$fg</code> and <code>$bg</code> which you use to extract
|
|
the escape sequences for given colours, for example
|
|
<code>${fg[red]}${bg[yellow]}</code> produces the sequences for red text on a
|
|
yellow background. So for example,</p>
|
|
<pre><code> PS1="%{${bg[white]}${fg[red]}%}%(?..(%?%))\
|
|
%{${fg[yellow]}${bg[black]}%}%# "
|
|
</code></pre>
|
|
<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><span id="l20"></span></p>
|
|
<h3 id="257-named-directories"><a class="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><span id="l21"></span></p>
|
|
<h3 id="258-go-faster-options-for-power-users"><a class="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>
|
|
<p><strong><code>EXTENDED_GLOB</code></strong></p>
|
|
<p>Patterns, to match the name of files and other things, can be very
|
|
sophisticated in zsh, but to get the most out of them you need to use
|
|
this option, as otherwise certain features are not enabled, so that
|
|
people used to simpler patterns (maybe just `<code>*</code>', `<code>?</code>' and
|
|
`<code>[...]</code>') are not confused by strange happenings. I'll say much more
|
|
about zsh's pattern features, but this is to remind you that you need
|
|
this option if you're doing anything clever with `<code>~</code>', `<code>#</code>', `<code>^</code>'
|
|
or globbing flags --- and also to remind you that those characters can
|
|
have strange effects if you have the option set.</p>
|
|
<p><strong><code>MULTIOS</code></strong></p>
|
|
<p>I mentioned above that to get zsh to behave like ksh you needed to set
|
|
<code>NO_MULTIOS</code>, but I didn't say what the <code>MULTIOS</code> option did. It has two
|
|
different effects for output and input.</p>
|
|
<p>First, for output. Here it's an alternative to the <code>tee</code> programme. I've
|
|
mentioned once, but haven't described in detail, that you could use
|
|
<code>>filename</code> to tell the shell to send output into a file with a given
|
|
name instead of to the terminal. With <code>MULTIOS</code> set, you can have more
|
|
than one of those redirections on the command line:</p>
|
|
<pre><code> echo foo >file1 >file2
|
|
</code></pre>
|
|
<p>Here, `<code>foo</code>' will be written to <strong>both</strong> the named files; zsh copies
|
|
the output. The pipe mechanism, which I'll describe better in <a href="zshguide03.html#syntax">chapter
|
|
3</a>, is a sort of redirection into another
|
|
programme instead of into a file: <code>MULTIOS</code> affects this as well:</p>
|
|
<pre><code> echo foo >file1 | sed 's/foo/bar/'
|
|
</code></pre>
|
|
<p>Here, `<code>foo</code>' is again written to <code>file1</code>, but is also sent into the
|
|
pipe to the programme <code>sed</code> (`stream editor') which substitutes
|
|
`<code>foo</code>' into `<code>bar</code>' and (since there is no output redirection in this
|
|
part) prints it to the terminal.</p>
|
|
<p>Note that the second example above has several times been reported as a
|
|
bug, often in a form like:</p>
|
|
<pre><code> some_command 2>&1 >/dev/null | sed 's/foo/bar/'
|
|
</code></pre>
|
|
<p>The intention here is presumably to send standard error to standard
|
|
output (the `<code>2>&1</code>', a very commonly used shell hieroglyphic), and not
|
|
send standard output anywhere (the `<code>>/dev/null</code>'). (If you haven't met
|
|
the concept of `standard error', it's just another output channel which
|
|
goes to the same place as normal output unless you redirect it; it's
|
|
used, for example to send error messages to the terminal even if your
|
|
output is going somewhere else.) In this example, too, the <code>MULTIOS</code>
|
|
feature forces the original standard output to go to the pipe. You can
|
|
see this happening if we put in a version of `<code>some_command</code>':</p>
|
|
<pre><code> { echo foo error >&2; echo foo not error; } 2>&1 >/dev/null |
|
|
sed 's/foo/bar/'
|
|
</code></pre>
|
|
<p>where you can consider the stuff inside the `<code>{...}</code>' as a black box
|
|
that sends the message `foo error' to standard error, and `foo not
|
|
error' to standard output. With <code>MULTIOS</code>, however, the result is</p>
|
|
<pre><code> error bar
|
|
not error bar
|
|
</code></pre>
|
|
<p>because both have been sent into the pipe. Without <code>MULTIOS</code> you get the
|
|
expected result,</p>
|
|
<pre><code> error bar
|
|
</code></pre>
|
|
<p>as any other Bourne-style shell would produce. There</p>
|
|
<p>On input, <code>MULTIOS</code> arranges for a series of files to be read in order.
|
|
This time it's a bit like using the programme <code>cat</code>, which combines all
|
|
the files listed after it. In other words,</p>
|
|
<pre><code> cat file1 file2 | myprog
|
|
</code></pre>
|
|
<p>(where <code>myprog</code> is some programme that reads all the files sent to it as
|
|
input) can be replaced by</p>
|
|
<pre><code> myprog <file1 <file2
|
|
</code></pre>
|
|
<p>which does the same thing. Once again, a pipe counts as a redirection,
|
|
and the pipe is read from first, before any files listed after a `<code><</code>':</p>
|
|
<pre><code> echo then this >testfile
|
|
echo this first | cat <testfile
|
|
</code></pre>
|
|
<p><strong><code>CORRECT</code>, <code>CORRECT_ALL</code></strong></p>
|
|
<p>If you have <code>CORRECT</code> set, the shell will check all the commands you
|
|
type and if they don't exist, but there is one with a similar name, it
|
|
will ask you if you meant that one instead. You can type `<code>n</code>' for no,
|
|
don't correct, just go ahead; `<code>y</code>' for yes, correct it then go ahead;
|
|
`<code>a</code>' for abort, don't do anything; `<code>e</code>' for edit, return to the
|
|
editor to edit the same line again. Users of the new completion system
|
|
should note this is not the same correction you get there: it's just
|
|
simple correction of commands.</p>
|
|
<p><code>CORRECT_ALL</code> applies to all the words on the line. It's a little less
|
|
useful, because currently the shell has to assume that they are supposed
|
|
to be filenames, and will try to correct them if they don't exist as
|
|
such, but of course many of the arguments to a command are not
|
|
filenames. If particular commands generate too many attempts to correct
|
|
their arguments, you can turn this off by putting `<code>nocorrect</code>' in
|
|
front of the command name. An alias is a very good way of doing this, as
|
|
described next.</p>
|
|
<p><span id="l22"></span></p>
|
|
<h3 id="259-aliases"><a class="header" href="#259-aliases">2.5.9: aliases</a></h3>
|
|
<p>An alias is used like a command, but it expands into some other text
|
|
which is itself used as a command. For example,</p>
|
|
<pre><code> alias foo='print I said foo'
|
|
foo
|
|
</code></pre>
|
|
<p>prints (guess what) `<code>I said foo</code>'. Note the syntax for definition ---
|
|
you need the `<code>=</code>', and you need to make sure the whole alias is
|
|
treated by the shell as one word; you can give a whole list of aliases
|
|
to the same `<code>alias</code>' command. You may be able to think of some aliases
|
|
you want to define in your startup files; <code>.zshrc</code> is probably the right
|
|
place. If you have <code>CORRECT_ALL</code> set, the way to avoid the `<code>mkdir</code>'
|
|
command spell-checking its arguments --- which is useless, because they
|
|
<em>have</em> to be non-existent for the command to work --- is to define:</p>
|
|
<pre><code> alias mkdir='nocorrect mkdir'
|
|
</code></pre>
|
|
<p>This shows one useful feature about aliases: the alias can contain
|
|
something of the same name as itself. When it is encountered in the
|
|
expansion text (the right hand side), the shell knows it is not to
|
|
expand the alias again, but this time to treat it as a real command.
|
|
Note that functions do <em>not</em> have this property: functions are more
|
|
powerful than aliases and in some cases it is useful for them to call
|
|
themselves, It's a common mistake to have functions call themselves over
|
|
and over again until the shell complains. I'll describe ways round this
|
|
in <a href="zshguide03.html#syntax">chapter 3</a>.</p>
|
|
<p>One other way functions are more powerful than aliases is that functions
|
|
can take arguments while aliases can't --- in other words, there is no
|
|
way of referring inside the alias to what follows it on the command
|
|
line, unlike a function, and also unlike aliases in csh (because that
|
|
has no functions, that's why). It is just blindly expanded, and the
|
|
remainder of the command line stuck on the end. Hence aliases in zsh are
|
|
usually kept for quite simple things, and functions are written for
|
|
anything more complicated. You couldn't do that trick with
|
|
`<code>nocorrect</code>' using a function, though, since the function is called
|
|
too late: aliases are expanded straight away, so the <code>nocorrect</code> is
|
|
found in time to be useful. You can almost think of them as just plain
|
|
typing abbreviations.</p>
|
|
<p>Normal aliases only work when in command position, i.e. at the start of
|
|
the command line (more strictly, when zsh is expecting a command). There
|
|
are other things called `global aliases', which you define by the
|
|
`<code>-g</code>' option to <code>alias</code>, which will be expanded at any position on the
|
|
command line. You should think seriously before defining these, as they
|
|
can have a drastic effect. Note, however, that quoting a word, or even a
|
|
single character, will stop an alias being expanded for it.</p>
|
|
<p>I only tend to use aliases in interactive shells, so I define them from
|
|
<code>.zshrc</code>, but you may want to use <code>.zshenv</code> if you use aliases more
|
|
widely. In fact, to keep my <code>.zshrc</code> neat I save all the aliases in a
|
|
separate file called <code>.aliasrc</code> and in <code>.zshrc</code> I have:</p>
|
|
<pre><code> if [[ -r ~/.aliasrc ]]; then
|
|
. ~/.aliasrc
|
|
fi
|
|
</code></pre>
|
|
<p>which checks if there is a readable file <code>~/.aliasrc</code>, and if there is,
|
|
it runs it in exactly the same way the normal startup files are run. You
|
|
can use `<code>source</code>' instead of `<code>.</code>' if it means more to you; `<code>.</code>' is
|
|
the traditional Bourne and Korn shell name, however.</p>
|
|
<p><span id="l23"></span></p>
|
|
<h3 id="2510-environment-variables"><a class="header" href="#2510-environment-variables">2.5.10: Environment variables</a></h3>
|
|
<p>Often, the manual for a programme will tell you to define certain
|
|
environment variables, usually a collection of uppercase letters with
|
|
maybe numbers and the odd underscore. These can pass information to the
|
|
programme without you needing to use extra arguments. In zsh,
|
|
environment variables appear as ordinary shell parameters, although they
|
|
have to be defined slightly differently: strictly, the environment is a
|
|
special region outside the shell, and zsh has to be told to put a copy
|
|
there as well as keeping one of its own. The usual syntax is</p>
|
|
<pre><code> export VARNAME='value'
|
|
</code></pre>
|
|
<p>in other words, like an ordinary assignment, but with `<code>export</code>' in
|
|
front. Note there is no `<code>$</code>' before the name of the environment
|
|
variable; all `<code>export</code>' and similar statements work the same way. The
|
|
easiest place to put these is in <code>.zshenv</code> --- hence it's name.
|
|
Environment variables will be passed to any programmes run from a shell,
|
|
so it may be enough to define them in <code>.zlogin</code> or <code>.zprofile</code>: however,
|
|
any shell started for you non-interactively won't run those, and there
|
|
are other possible problems if you use a windowing system which is
|
|
started by a shell other than zsh or which doesn't run a shell start-up
|
|
file at all --- I had to tweak mine to make it do so. So <code>.zshenv</code> is
|
|
the safest place; it doesn't take long to define environment variables.
|
|
Other people will no doubt give you completely contradictory views, but
|
|
that's people for you.</p>
|
|
<p>Note that you can't export arrays. If you export a parameter, then
|
|
assign an array to it, nothing will appear in the environment; you can
|
|
use the external command `<code>printenv VARNAME</code>' (again no `<code>$</code>' because
|
|
the command needs to know the name, not the value) to check. There's a
|
|
more subtle problem with arrays, too. The <code>export</code> builtin is just a
|
|
special case of the builtin <strong>typeset</strong>, which defines a variable
|
|
without marking it for export to the environment. You might think you
|
|
could do</p>
|
|
<pre><code> typeset array=(this doesn\'t work)
|
|
</code></pre>
|
|
<p>but you can't --- the special array syntax is only understood when the
|
|
assignment does not follow a command, not in normal arguments like the
|
|
case here, so you have to put the array assignment on the next line.
|
|
This is a very easy mistake to make. More uses of <code>typeset</code> will be
|
|
described in <a href="zshguide03.html#syntax">chapter 3</a>; they include creating
|
|
local parameters in functions, and defining special attributes (of which
|
|
the `export' attribute is just one) for parameters.</p>
|
|
<p><span id="l24"></span></p>
|
|
<h3 id="2511-path"><a class="header" href="#2511-path">2.5.11: Path</a></h3>
|
|
<p>It helps to be able to find external programmes, i.e. anything not part
|
|
of the shell, any command other than a builtin, function or alias. The
|
|
<code>$path</code> array is used for this. Actually, what the system needs is the
|
|
environment variable <code>$PATH</code>, which contains a list of directories in
|
|
which to search for programmes, separated from each other by a colon.
|
|
These directories are the individual components of the array <code>$path</code>. So
|
|
if <code>$path</code> contains</p>
|
|
<pre><code> path=(/bin /usr/bin /usr/local/bin .)
|
|
</code></pre>
|
|
<p>then <code>$PATH</code> will automatically contain the effect of</p>
|
|
<pre><code> PATH=/bin:/usr/bin:/usr/local/bin:.
|
|
</code></pre>
|
|
<p>without you having to set that. The idea is simply that, while the
|
|
system needs <code>$PATH</code> because it doesn't understand arrays, it's much
|
|
more flexible to be able to use arrays within the shell and hence pretty
|
|
much forget about the <code>$PATH</code> form.</p>
|
|
<p>Changes to the path are similar to changes to environment variables
|
|
described above, so all that applies. There's a slight difficulty in
|
|
setting <code>$path</code> in <code>.zshenv</code> however, even though the reasons given
|
|
above for doing so still apply. Usually, the path will be set for you,
|
|
either by the system, or by the system administrator in one of the
|
|
global start up files, and if you change path you will simply want to
|
|
add to it. But if your <code>.zshenv</code> contains</p>
|
|
<pre><code> path=(~/bin ~/progs/bin $path)
|
|
</code></pre>
|
|
<p>--- which is the right way of adding something to the front of <code>$path</code>
|
|
--- then every time <code>.zshenv</code> is called, <code>~/bin</code> and <code>~/progs/bin</code> are
|
|
stuck in front, so if you start another zsh you will have two sets
|
|
there.</p>
|
|
<p>You can add tests to see if something's already there, of course. Zsh
|
|
conveniently allows you to test for the existence of elements in an
|
|
array. By preceding an array index by <code>(r)</code> (for reverse), it will try
|
|
to find a matching element and return that, else an empty string. Here's
|
|
a way of doing that (but don't add this yet, see the next paragraph):</p>
|
|
<pre><code> for dir in ~/bin ~/progs/bin; do
|
|
if [[ -z ${path[(r)$dir]} ]]; then
|
|
path=($dir $path)
|
|
fi
|
|
done
|
|
</code></pre>
|
|
<p>That <code>for</code>... <code>do</code> ... <code>done</code> is another special shell construct. It
|
|
takes each thing after `<code>in</code>' and assigns it in turn to the parameter
|
|
named before the `<code>in</code>' --- <code>$dir</code>, but because this is a form of
|
|
assignment, the `<code>$</code>' is left off --- so the first time round it has
|
|
the effect of <code>dir=~/bin</code>, and the next time <code>dir=~/progs/bin</code>. Then it
|
|
executes what's in the loop. The test <code>-z</code> checks that what follows is
|
|
empty: in this case it will be if the directory <code>$dir</code> is not yet in
|
|
<code>$path</code>, so it goes ahead and adds it in front. Note that the
|
|
directories get added in the reverse of the order they appear.</p>
|
|
<p>Actually, however, zsh takes all that trouble away from you. The
|
|
incantation `<code>typeset -U path</code>', where the <code>-U</code> stands for unique,
|
|
tells the shell that it should not add anything to <code>$path</code> if it's there
|
|
already. To be precise, it keeps only the left-most occurrence, so if
|
|
you added something at the end it will disappear and if you added
|
|
something at the beginning, the old one will disappear. Thus the
|
|
following works nicely in <code>.zshenv</code>:</p>
|
|
<pre><code> typeset -U path
|
|
path=(~/bin ~/progs/bin $path)
|
|
</code></pre>
|
|
<p>and you can put down that `<code>for</code>' stuff as a lesson in shell
|
|
programming. You can list all the variables which have uniqueness turned
|
|
on by typing `<code>typeset +U</code>', with `<code>+</code>' instead of `<code>-</code>', because in
|
|
the latter case the shell would show the values of the parameters as
|
|
well, which isn't what you need here. The <code>-U</code> flag will also work with
|
|
colon-separated arrays, like <code>$PATH</code>.</p>
|
|
<p><span id="l25"></span></p>
|
|
<h3 id="2512-mail"><a class="header" href="#2512-mail">2.5.12: Mail</a></h3>
|
|
<p>Zsh will check for new mail for you. If all you need is to be reminded
|
|
of something arriving in your normal folder every now and then, you just
|
|
need to set the parameter <code>$MAIL</code> to wherever that is: it's typically
|
|
one of <code>/usr/spool/mail</code>, <code>/var/spool/mail</code>, or <code>/var/mail</code>.</p>
|
|
<p>The array <code>$mailpath</code> allows more possibilities. Like <code>$path</code>, it has a
|
|
colleague in uppercase, <code>$MAILPATH</code>, which is a colon-separated array.
|
|
The system doesn't need that, this time, so it's mainly there so that
|
|
you can export it to another version of zsh; exporting arrays won't
|
|
work. As may by now be painfully clear, if you set in <code>.zshenv</code> or
|
|
<code>.zshrc</code>, you don't need to export it, because it's set in each instance
|
|
of the shell. The elements of <code>$mailpath</code> work like <code>$MAIL</code>, so you can
|
|
specify different places where mail arrives. That's most useful if you
|
|
have a programme like <code>filter</code> or <code>procmail</code> running to redistribute
|
|
arriving mail to different folders. You can specify a different message
|
|
for each folder by putting `<code>?</code><em>message</em>' at the end. For example, mine
|
|
looks like this.</p>
|
|
<pre><code> mailpref=/temp/pws/Mail
|
|
mailpath=($mailpref/newmail
|
|
$mailpref/zsh-new'?New zsh mail'
|
|
$mailpref/list-new'?New list mail'
|
|
$mailpref/urth-new'?New Urth mail')
|
|
</code></pre>
|
|
<p>Note that zsh knows the array isn't finished until the `)', even though
|
|
the elements are on different lines; this is one very good reason for
|
|
setting <code>$mailpath</code> rather than <code>$MAILPATH</code>, which needs one long chunk.</p>
|
|
<p>The other parameter of interest is <code>$MAILCHECK</code>, which gives the
|
|
frequency in seconds when zsh should check for new mail. The default is
|
|
60. Actually, zsh only checks just after a command has finished running
|
|
and it is about to print a prompt. Since checking files doesn't take
|
|
long, you can usually set this to its minimum value, which is
|
|
<code>MAILCHECK=1</code>; zero doesn't work because it switches off checking. One
|
|
reason why you wouldn't want to do that might be because <code>$MAIL</code> and
|
|
<code>$mailpath</code> can contain directories instead of ordinary files; these
|
|
will be checked recursively for any files with something new in them, so
|
|
this can be slow.</p>
|
|
<p>Finally, there is one associated option, <code>MAIL_WARNING</code> (though
|
|
<code>MAIL_WARN</code> is also accepted for the same thing for reasons of
|
|
compatibility with less grammatical shells). The shell remembers when it
|
|
found the mail file was checked; next time it checks, it compares the
|
|
date. If there is no new mail, but the date of the file changed anyway,
|
|
it will print a warning message. This will happen if you read the mail
|
|
with your mail reader and put the messages somewhere else. Presumably
|
|
you <em>know</em> you did that, so the warning may not be all that useful.</p>
|
|
<p><span id="l26"></span></p>
|
|
<h3 id="2513-other-path-like-things"><a class="header" href="#2513-other-path-like-things">2.5.13: Other path-like things</a></h3>
|
|
<p>There are other pairs like <code>$path</code> and <code>$PATH</code>. I will keep back talk of
|
|
<code>$cdpath</code> until I say more about the way zsh handles directories. When I
|
|
mentioned <code>$fpath</code>, I didn't say there was also <code>$FPATH</code>, but there is.
|
|
Then there is <code>$manpath</code> and <code>$MANPATH</code>; these aren't used by the shell
|
|
at all, but <code>$MANPATH</code>, if exported, is used by the <strong>man</strong> external
|
|
command, and <code>$manpath</code> gives an easier way to set it.</p>
|
|
<p>From 3.1.6 there is a mechanism to define your own such combinations; if
|
|
this had been available before, there would have been no need to build
|
|
in <code>$manpath</code> and <code>$MANPATH</code>. In <code>.zshenv</code> you would put,</p>
|
|
<pre><code> export -TU TEXINPUTS texinputs
|
|
</code></pre>
|
|
<p>to define such a pair. The <code>-T</code> (for tie) is the key to that; I've used
|
|
`<code>export</code>' even though the basic variable declaration command is
|
|
`<code>typeset</code>' because you nearly always want to get the colon-separated
|
|
version (<code>$TEXINPUTS</code> here) visible to the environment, and I've set
|
|
<code>-U</code> as described above for <code>$path</code> because it's a neat feature anyway.
|
|
Now you can assign to the array <code>$texinputs</code> and let the programme (TeX
|
|
or its derivatives) see <code>$TEXINPUTS</code>. Another useful variable to do this
|
|
with is <code>$LD_LIBRARY_PATH</code>, which on most modern versions of UNIX (and
|
|
Linux) tells the system where to find the libraries which provide extra
|
|
functions when it runs a programme.</p>
|
|
<p><span id="l27"></span></p>
|
|
<h3 id="2514-version-specific-things"><a class="header" href="#2514-version-specific-things">2.5.14: Version-specific things</a></h3>
|
|
<p>Since zsh changes faster than almost any other command interpreter known
|
|
to humankind, you will often find you need to find out what version you
|
|
are using. This can get a bit verbose; indeed, the parameter you need to
|
|
check, which is now <code>$ZSH_VERSION</code>, used simply to be called <code>$VERSION</code>
|
|
before version <code>3.0</code>. If you are not using legacy software of that kind,
|
|
you can probably get away with tests like this:</p>
|
|
<pre><code> if [[ $ZSH_VERSION == 3.1.<5->* ||
|
|
$ZSH_VERSION == 3.<2->* ||
|
|
$ZSH_VERSION == <4->* ]]; then
|
|
# set feature which appeared first in 3.1.5
|
|
fi
|
|
</code></pre>
|
|
<p>It's like that to be futureproof: it says that if this is a 3.1 release,
|
|
it has to be at least 3.1.5, but any 3.2 release (there weren't any), or
|
|
any release 4 or later, will also be OK. The `<code><5-></code>' etc. are advanced
|
|
pattern matching tests: pattern matching uses the same symbols as
|
|
globbing, but to test other things, here what's on the left of the
|
|
`<code>==</code>'. This one matches any number which is at least 5, for example 6
|
|
or 10 or 252, but not 1 or 4. There are also development releases;
|
|
nowadays the version numbers look like <em>X</em><code>.</code><em>Y</em><code>.</code><em>Z</em>-<em>tag</em>-<em>N</em> (<em>tag</em>
|
|
is some short word, the others are numbers) but unless you're keeping up
|
|
with development you won't need to look for those, since they aren't
|
|
released officially. That `<code>==</code>' in the test could also be just `<code>=</code>',
|
|
but the manual says the former is preferred, so I've used them here,
|
|
even though people usually don't bother.</p>
|
|
<p>Version 4 of zsh provides a function <code>is-at-least</code> to do this for you:
|
|
it looks only at the numbers <em>X</em>, <em>Y</em> and <em>Z</em> (and <em>N</em> if it exists),
|
|
ignoring all letters and punctuation. You give it the minimum version of
|
|
the shell you need and it returns true if the current shell is recent
|
|
enough. For example, `<code>is-at-least 3.1.6-pws-9</code>' will return true if
|
|
the current version of zsh is 3.1.6-dev-20 (or 3.1.9, or 4.0.1, and so
|
|
on), which is the correct behaviour. As with any other shell function,
|
|
you have to arrange for <code>is-at-least</code> to be <code>autoload</code>ed if you want to
|
|
use it.</p>
|
|
<p><span id="l28"></span></p>
|
|
<h3 id="2515-everything-else"><a class="header" href="#2515-everything-else">2.5.15: Everything else</a></h3>
|
|
<p>There are many other possibilities for things to go in startup files; in
|
|
particular, I haven't touched on defining things for the line editor and
|
|
setting up completion. There's quite a lot to explain for those, so I'll
|
|
come back to those in the appropriate chapters. You just need to
|
|
remember that all that stuff should go in <code>.zshrc</code>, since you need it
|
|
for all interactive shells, and for no others.</p>
|
|
|
|
</main>
|
|
|
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
|
<!-- Mobile navigation buttons -->
|
|
<a rel="prev" href="zshguide01.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
|
<i class="fa fa-angle-left"></i>
|
|
</a>
|
|
|
|
<a rel="next" href="zshguide03.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
|
<i class="fa fa-angle-right"></i>
|
|
</a>
|
|
|
|
<div style="clear: both"></div>
|
|
</nav>
|
|
</div>
|
|
</div>
|
|
|
|
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
|
<a rel="prev" href="zshguide01.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
|
<i class="fa fa-angle-left"></i>
|
|
</a>
|
|
|
|
<a rel="next" href="zshguide03.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
|
<i class="fa fa-angle-right"></i>
|
|
</a>
|
|
</nav>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<script type="text/javascript">
|
|
window.playground_copyable = true;
|
|
</script>
|
|
|
|
|
|
<script src="elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
|
|
<script src="mark.min.js" type="text/javascript" charset="utf-8"></script>
|
|
<script src="searcher.js" type="text/javascript" charset="utf-8"></script>
|
|
|
|
<script src="clipboard.min.js" type="text/javascript" charset="utf-8"></script>
|
|
<script src="highlight.js" type="text/javascript" charset="utf-8"></script>
|
|
<script src="book.js" type="text/javascript" charset="utf-8"></script>
|
|
|
|
<!-- Custom JS scripts -->
|
|
|
|
|
|
</body>
|
|
</html>
|