Initial commit

This commit is contained in:
Jeffrey Serio 2021-05-10 19:29:21 -05:00
commit 903ea5ffb0
128 changed files with 124610 additions and 0 deletions

44
README.md Normal file
View File

@ -0,0 +1,44 @@
# zsh-manual-mdbook
This is a markdown version of the [Zsh Manual](http://zsh.sourceforge.net/Doc/).
It is generated with a Bash script that removes some non-markdown-friendly
elements and converts the .html files to markdown using Pandoc. The SUMMARY.md
is generated with a Python script that scrapes the web page of the Zsh Manual's
table of contents.
The scripts contained in this repository are highly specialized for this
use-case and do not scale to anything else, but I've tried to make them as
abstract as possible, so they should work on anything with the same HTML
structure.
## Why not just use the plain old Zsh Manual?
An [mdbook](https://rust-lang.github.io/mdBook/) version is easier to browse and is more
aesthetically satisfying.
## Running/testing a local version
```bash
# Ensure mdbook is installed
cargo install mdbook
# Clone this repository
git clone https://github.com/hyperreal64/zsh-manual-mdbook
# Install Python dependencies
cd zsh-manual-mdbook
pip install -r requirements.txt
# Initialize an mdbook project at (e.g.) ~/zsh-mdbook
mdbook init ~/zsh-mdbook
# Remove sample items from mdbook src
cd ~/zsh-mdbook/src
rm *.md
# Return to repository clone and run the make-mdbook script
./make-mdbook.sh
# Copy items to mdbook src
cp -rf ~/zsh_doc_tmp/mdbook_src/* ~/zsh-mdbook/src/
```

6
book.toml Normal file
View File

@ -0,0 +1,6 @@
[book]
authors = ["Jeffrey Serio"]
language = "en"
multilingual = false
src = "src"
title = "Zsh Manual"

1
book/.nojekyll Normal file
View File

@ -0,0 +1 @@
This file makes sure that Github Pages doesn't process mdBook's output.

237
book/404.html Normal file
View File

@ -0,0 +1,237 @@
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title></title>
<base href="/">
<!-- 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 -->
</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 "><a href="The-Z-Shell-Manual.html"><strong aria-hidden="true">1.</strong> The Z Shell Manual</a></li><li class="chapter-item expanded "><a href="Introduction.html"><strong aria-hidden="true">2.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="Roadmap.html"><strong aria-hidden="true">3.</strong> Roadmap</a></li><li class="chapter-item expanded "><a href="Invocation.html"><strong aria-hidden="true">4.</strong> Invocation</a></li><li class="chapter-item expanded "><a href="Files.html"><strong aria-hidden="true">5.</strong> Files</a></li><li class="chapter-item expanded "><a href="Shell-Grammar.html"><strong aria-hidden="true">6.</strong> Shell Grammar</a></li><li class="chapter-item expanded "><a href="Redirection.html"><strong aria-hidden="true">7.</strong> Redirection</a></li><li class="chapter-item expanded "><a href="Command-Execution.html"><strong aria-hidden="true">8.</strong> Command Execution</a></li><li class="chapter-item expanded "><a href="Functions.html"><strong aria-hidden="true">9.</strong> Functions</a></li><li class="chapter-item expanded "><a href="Jobs-_0026-Signals.html"><strong aria-hidden="true">10.</strong> Jobs &amp; Signals</a></li><li class="chapter-item expanded "><a href="Arithmetic-Evaluation.html"><strong aria-hidden="true">11.</strong> Arithmetic Evaluation</a></li><li class="chapter-item expanded "><a href="Conditional-Expressions.html"><strong aria-hidden="true">12.</strong> Conditional Expressions</a></li><li class="chapter-item expanded "><a href="Prompt-Expansion.html"><strong aria-hidden="true">13.</strong> Prompt Expansion</a></li><li class="chapter-item expanded "><a href="Expansion.html"><strong aria-hidden="true">14.</strong> Expansion</a></li><li class="chapter-item expanded "><a href="Parameters.html"><strong aria-hidden="true">15.</strong> Parameters</a></li><li class="chapter-item expanded "><a href="Options.html"><strong aria-hidden="true">16.</strong> Options</a></li><li class="chapter-item expanded "><a href="Shell-Builtin-Commands.html"><strong aria-hidden="true">17.</strong> Shell Builtin Commands</a></li><li class="chapter-item expanded "><a href="Zsh-Line-Editor.html"><strong aria-hidden="true">18.</strong> Zsh Line Editor</a></li><li class="chapter-item expanded "><a href="Completion-Widgets.html"><strong aria-hidden="true">19.</strong> Completion Widgets</a></li><li class="chapter-item expanded "><a href="Completion-System.html"><strong aria-hidden="true">20.</strong> Completion System</a></li><li class="chapter-item expanded "><a href="Completion-Using-compctl.html"><strong aria-hidden="true">21.</strong> Completion Using compctl</a></li><li class="chapter-item expanded "><a href="Zsh-Modules.html"><strong aria-hidden="true">22.</strong> Zsh Modules</a></li><li class="chapter-item expanded "><a href="Calendar-Function-System.html"><strong aria-hidden="true">23.</strong> Calendar Function System</a></li><li class="chapter-item expanded "><a href="TCP-Function-System.html"><strong aria-hidden="true">24.</strong> TCP Function System</a></li><li class="chapter-item expanded "><a href="Zftp-Function-System.html"><strong aria-hidden="true">25.</strong> Zftp Function System</a></li><li class="chapter-item expanded "><a href="User-Contributions.html"><strong aria-hidden="true">26.</strong> User Contributions</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>
</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 Manual</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" name="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>
<h1 id="document-not-found-404"><a class="header" href="#document-not-found-404">Document not found (404)</a></h1>
<p>This URL is invalid, sorry. Please use the navigation bar or search to continue.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
</nav>
</div>
<!-- Livereload script (if served using the cli tool) -->
<script type="text/javascript">
var socket = new WebSocket("ws://localhost:3000/__livereload");
socket.onmessage = function (event) {
if (event.data === "reload") {
socket.close();
location.reload();
}
};
window.onbeforeunload = function() {
socket.close();
}
</script>
<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>

View File

@ -0,0 +1,588 @@
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Arithmetic Evaluation - Zsh Manual</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 -->
</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 "><a href="The-Z-Shell-Manual.html"><strong aria-hidden="true">1.</strong> The Z Shell Manual</a></li><li class="chapter-item expanded "><a href="Introduction.html"><strong aria-hidden="true">2.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="Roadmap.html"><strong aria-hidden="true">3.</strong> Roadmap</a></li><li class="chapter-item expanded "><a href="Invocation.html"><strong aria-hidden="true">4.</strong> Invocation</a></li><li class="chapter-item expanded "><a href="Files.html"><strong aria-hidden="true">5.</strong> Files</a></li><li class="chapter-item expanded "><a href="Shell-Grammar.html"><strong aria-hidden="true">6.</strong> Shell Grammar</a></li><li class="chapter-item expanded "><a href="Redirection.html"><strong aria-hidden="true">7.</strong> Redirection</a></li><li class="chapter-item expanded "><a href="Command-Execution.html"><strong aria-hidden="true">8.</strong> Command Execution</a></li><li class="chapter-item expanded "><a href="Functions.html"><strong aria-hidden="true">9.</strong> Functions</a></li><li class="chapter-item expanded "><a href="Jobs-_0026-Signals.html"><strong aria-hidden="true">10.</strong> Jobs &amp; Signals</a></li><li class="chapter-item expanded "><a href="Arithmetic-Evaluation.html" class="active"><strong aria-hidden="true">11.</strong> Arithmetic Evaluation</a></li><li class="chapter-item expanded "><a href="Conditional-Expressions.html"><strong aria-hidden="true">12.</strong> Conditional Expressions</a></li><li class="chapter-item expanded "><a href="Prompt-Expansion.html"><strong aria-hidden="true">13.</strong> Prompt Expansion</a></li><li class="chapter-item expanded "><a href="Expansion.html"><strong aria-hidden="true">14.</strong> Expansion</a></li><li class="chapter-item expanded "><a href="Parameters.html"><strong aria-hidden="true">15.</strong> Parameters</a></li><li class="chapter-item expanded "><a href="Options.html"><strong aria-hidden="true">16.</strong> Options</a></li><li class="chapter-item expanded "><a href="Shell-Builtin-Commands.html"><strong aria-hidden="true">17.</strong> Shell Builtin Commands</a></li><li class="chapter-item expanded "><a href="Zsh-Line-Editor.html"><strong aria-hidden="true">18.</strong> Zsh Line Editor</a></li><li class="chapter-item expanded "><a href="Completion-Widgets.html"><strong aria-hidden="true">19.</strong> Completion Widgets</a></li><li class="chapter-item expanded "><a href="Completion-System.html"><strong aria-hidden="true">20.</strong> Completion System</a></li><li class="chapter-item expanded "><a href="Completion-Using-compctl.html"><strong aria-hidden="true">21.</strong> Completion Using compctl</a></li><li class="chapter-item expanded "><a href="Zsh-Modules.html"><strong aria-hidden="true">22.</strong> Zsh Modules</a></li><li class="chapter-item expanded "><a href="Calendar-Function-System.html"><strong aria-hidden="true">23.</strong> Calendar Function System</a></li><li class="chapter-item expanded "><a href="TCP-Function-System.html"><strong aria-hidden="true">24.</strong> TCP Function System</a></li><li class="chapter-item expanded "><a href="Zftp-Function-System.html"><strong aria-hidden="true">25.</strong> Zftp Function System</a></li><li class="chapter-item expanded "><a href="User-Contributions.html"><strong aria-hidden="true">26.</strong> User Contributions</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>
</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 Manual</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" name="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="#11-arithmetic-evaluation">11 Arithmetic Evaluation</a></li>
</ul>
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<p><span id="Arithmetic-Evaluation"></span>
<span id="Arithmetic-Evaluation-1"></span></p>
<h1 id="11-arithmetic-evaluation"><a class="header" href="#11-arithmetic-evaluation">11 Arithmetic Evaluation</a></h1>
<p><span id="index-arithmetic-evaluation"></span>
<span id="index-evaluation_002c-arithmetic"></span>
<span id="index-let_002c-use-of"></span></p>
<p>The shell can perform integer and floating point arithmetic, either
using the builtin <code>let</code>, or via a substitution of the form
<code>$((``...``))</code>. For integers, the shell is usually compiled to use
8-byte precision where this is available, otherwise precision is 4
bytes. This can be tested, for example, by giving the command <code>print - $(( 12345678901 ))</code>; if the number appears unchanged, the precision is
at least 8 bytes. Floating point arithmetic always uses the double
type with whatever corresponding precision is provided by the compiler
and the library.</p>
<p>The <code>let</code> builtin command takes arithmetic expressions as arguments;
each is evaluated separately. Since many of the arithmetic operators, as
well as spaces, require quoting, an alternative form is provided: for
any command which begins with a <code>((</code>, all the characters until a
matching <code>))</code> are treated as a quoted expression and arithmetic
expansion performed as for an argument of <code>let</code>. More precisely,
<code>((``...``))</code> is equivalent to <code>let &quot;``...``&quot;</code>. The return status
is 0 if the arithmetic value of the expression is non-zero, 1 if it is
zero, and 2 if an error occurred.</p>
<p>For example, the following statement</p>
<div class="example">
<pre><code class="language-example">(( val = 2 + 1 ))
</code></pre>
</div>
<p>is equivalent to</p>
<div class="example">
<pre><code class="language-example">let &quot;val = 2 + 1&quot;
</code></pre>
</div>
<p>both assigning the value 3 to the shell variable <code>val</code> and returning a
zero status.</p>
<p><span id="index-arithmetic-base"></span>
<span id="index-bases_002c-in-arithmetic"></span></p>
<p>Integers can be in bases other than 10. A leading <code>0x</code> or <code>0X</code>
denotes hexadecimal and a leading <code>0b</code> or <code>0B</code> binary. Integers may
also be of the form <code>base``#``n</code>, where <code>base</code> is a decimal number
between two and thirty-six representing the arithmetic base and <code>n</code> is a
number in that base (for example, <code>16#ff</code> is 255 in hexadecimal). The
<code>base``#</code> may also be omitted, in which case base 10 is used. For
backwards compatibility the form <code>[``base``]``n</code> is also accepted.</p>
<p>An integer expression or a base given in the form <code>base``#``n</code> may
contain underscores (<code>_</code>) after the leading digit for visual guidance;
these are ignored in computation. Examples are <code>1_000_000</code> or
<code>0xffff_ffff</code> which are equivalent to <code>1000000</code> and <code>0xffffffff</code>
respectively.</p>
<p>It is also possible to specify a base to be used for output in the form
<code>[#``base``]</code>, for example <code>[#16]</code>. This is used when outputting
arithmetical substitutions or when assigning to scalar parameters, but
an explicitly defined integer or floating point parameter will not be
affected. If an integer variable is implicitly defined by an arithmetic
expression, any base specified in this way will be set as the variables
output arithmetic base as if the option <code>-i</code> <code>base</code> to the <code>typeset</code>
builtin had been used. The expression has no precedence and if it occurs
more than once in a mathematical expression, the last encountered is
used. For clarity it is recommended that it appear at the beginning of
an expression. As an example:</p>
<div class="example">
<pre><code class="language-example">typeset -i 16 y
print $(( [#8] x = 32, y = 32 ))
print $x $y
</code></pre>
</div>
<p>outputs first <code>8#40</code>, the rightmost value in the given output base,
and then <code>8#40 16#20</code>, because <code>y</code> has been explicitly declared to
have output base 16, while <code>x</code> (assuming it does not already exist) is
implicitly typed by the arithmetic evaluation, where it acquires the
output base 8.</p>
<p>The <code>base</code> may be replaced or followed by an underscore, which may
itself be followed by a positive integer (if it is missing the value 3
is used). This indicates that underscores should be inserted into the
output string, grouping the number for visual clarity. The following
integer specifies the number of digits to group together. For example:</p>
<div class="example">
<pre><code class="language-example">setopt cbases
print $(( [#16_4] 65536 ** 2 ))
</code></pre>
</div>
<p>outputs <code>0x1_0000_0000</code>.</p>
<p>The feature can be used with floating point numbers, in which case the
base must be omitted; grouping is away from the decimal point. For
example,</p>
<div class="example">
<pre><code class="language-example">zmodload zsh/mathfunc
print $(( [#_] sqrt(1e7) ))
</code></pre>
</div>
<p>outputs <code>3_162.277_660_168_379_5</code> (the number of decimal places shown
may vary).</p>
<p><span id="index-C_005fBASES_002c-use-of"></span>
<span id="index-OCTAL_005fZEROES_002c-use-of"></span></p>
<p>If the <code>C_BASES</code> option is set, hexadecimal numbers are output in the
standard C format, for example <code>0xFF</code> instead of the usual <code>16#FF</code>.
If the option <code>OCTAL_ZEROES</code> is also set (it is not by default), octal
numbers will be treated similarly and hence appear as <code>077</code> instead of
<code>8#77</code>. This option has no effect on the output of bases other than
hexadecimal and octal, and these formats are always understood on input.</p>
<p>When an output base is specified using the <code>[#``base``]</code> syntax, an
appropriate base prefix will be output if necessary, so that the value
output is valid syntax for input. If the <code>#</code> is doubled, for example
<code>[##16]</code>, then no base prefix is output.</p>
<p>Floating point constants are recognized by the presence of a decimal
point or an exponent. The decimal point may be the first character of
the constant, but the exponent character <code>e</code> or <code>E</code> may not, as it will
be taken for a parameter name. All numeric parts (before and after the
decimal point and in the exponent) may contain underscores after the
leading digit for visual guidance; these are ignored in computation.</p>
<p><span id="index-arithmetic-operators"></span>
<span id="index-operators_002c-arithmetic"></span></p>
<p>An arithmetic expression uses nearly the same syntax and associativity
of expressions as in C.</p>
<p>In the native mode of operation, the following operators are supported
(listed in decreasing order of precedence):</p>
<ul>
<li>
<p><code>+ - ! ~ ++ </code><br />
unary plus/minus, logical NOT, complement, {pre,post}{in,de}crement</p>
</li>
<li>
<p><code>&lt;&lt; &gt;&gt;</code><br />
bitwise shift left, right</p>
</li>
<li>
<p><code>&amp;</code><br />
bitwise AND</p>
</li>
<li>
<p><code>^</code><br />
bitwise XOR</p>
</li>
<li>
<p><code>|</code><br />
bitwise OR</p>
</li>
<li>
<p><code>**</code><br />
exponentiation</p>
</li>
<li>
<p><code>* / %</code><br />
multiplication, division, modulus (remainder)</p>
</li>
<li>
<p><code>+ -</code><br />
addition, subtraction</p>
</li>
<li>
<p><code>&lt; &gt; &lt;= &gt;=</code><br />
comparison</p>
</li>
<li>
<p><code>== !=</code><br />
equality and inequality</p>
</li>
<li>
<p><code>&amp;&amp;</code><br />
logical AND</p>
</li>
<li>
<p><code>|| ^^</code><br />
logical OR, XOR</p>
</li>
<li>
<p><code>? :</code><br />
ternary operator</p>
</li>
<li>
<p><code>= += -= *= /= %= &amp;= ^= |= &lt;&lt;= &gt;&gt;= &amp;&amp;= ||= ^^= **=</code><br />
assignment</p>
</li>
<li>
<p><code>,</code><br />
comma operator</p>
</li>
</ul>
<p>The operators <code>&amp;&amp;</code>, <code>||</code>, <code>&amp;&amp;=</code>, and <code>||=</code> are short-circuiting,
and only one of the latter two expressions in a ternary operator is
evaluated. Note the precedence of the bitwise AND, OR, and XOR
operators.</p>
<p>With the option <code>C_PRECEDENCES</code> the precedences (but no other
properties) of the operators are altered to be the same as those in most
other languages that support the relevant operators:</p>
<ul>
<li>
<p><code>+ - ! ~ ++ </code><br />
unary plus/minus, logical NOT, complement, {pre,post}{in,de}crement</p>
</li>
<li>
<p><code>**</code><br />
exponentiation</p>
</li>
<li>
<p><code>* / %</code><br />
multiplication, division, modulus (remainder)</p>
</li>
<li>
<p><code>+ -</code><br />
addition, subtraction</p>
</li>
<li>
<p><code>&lt;&lt; &gt;&gt;</code><br />
bitwise shift left, right</p>
</li>
<li>
<p><code>&lt; &gt; &lt;= &gt;=</code><br />
comparison</p>
</li>
<li>
<p><code>== !=</code><br />
equality and inequality</p>
</li>
<li>
<p><code>&amp;</code><br />
bitwise AND</p>
</li>
<li>
<p><code>^</code><br />
bitwise XOR</p>
</li>
<li>
<p><code>|</code><br />
bitwise OR</p>
</li>
<li>
<p><code>&amp;&amp;</code><br />
logical AND</p>
</li>
<li>
<p><code>^^</code><br />
logical XOR</p>
</li>
<li>
<p><code>||</code><br />
logical OR</p>
</li>
<li>
<p><code>? :</code><br />
ternary operator</p>
</li>
<li>
<p><code>= += -= *= /= %= &amp;= ^= |= &lt;&lt;= &gt;&gt;= &amp;&amp;= ||= ^^= **=</code><br />
assignment</p>
</li>
<li>
<p><code>,</code><br />
comma operator</p>
</li>
</ul>
<p>Note the precedence of exponentiation in both cases is below that of
unary operators, hence <code>-3**2</code> evaluates as <code>9</code>, not <code>-9</code>. Use
parentheses where necessary: <code>-(3**2)</code>. This is for compatibility with
other shells.</p>
<p><span id="index-mathematical-functions_002c-use-of"></span>
<span id="index-functions_002c-math_002c-use-of"></span></p>
<p>Mathematical functions can be called with the syntax
<code>func``(``args``)</code>, where the function decides if the <code>args</code> is
used as a string or a comma-separated list of arithmetic expressions.
The shell currently defines no mathematical functions by default, but
the module <code>zsh/mathfunc</code> may be loaded with the <code>zmodload</code> builtin to
provide standard floating point mathematical functions.</p>
<p>An expression of the form <code>##``x</code> where <code>x</code> is any character sequence
such as <code>a</code>, <code>^A</code>, or <code>\M-\C-x</code> gives the value of this character
and an expression of the form <code>#``name</code> gives the value of the first
character of the contents of the parameter <code>name</code>. Character values are
according to the character set used in the current locale; for multibyte
character handling the option <code>MULTIBYTE</code> must be set. Note that this
form is different from <code>$#``name</code>, a standard parameter substitution
which gives the length of the parameter <code>name</code>. <code>#\</code> is accepted
instead of <code>##</code>, but its use is deprecated.</p>
<p>Named parameters and subscripted arrays can be referenced by name within
an arithmetic expression without using the parameter expansion syntax.
For example,</p>
<div class="example">
<pre><code class="language-example">((val2 = val1 * 2))
</code></pre>
</div>
<p>assigns twice the value of <code>$val1</code> to the parameter named <code>val2</code>.</p>
<p>An internal integer representation of a named parameter can be specified
with the <code>integer</code> builtin.
<span id="index-parameters_002c-integer"></span>
<span id="index-integer-parameters"></span>
<span id="index-integer_002c-use-of"></span> Arithmetic evaluation is
performed on the value of each assignment to a named parameter declared
integer in this manner. Assigning a floating point number to an integer
results in rounding towards zero.</p>
<p><span id="index-parameters_002c-floating-point"></span>
<span id="index-floating-point-parameters"></span>
<span id="index-float_002c-use-of"></span></p>
<p>Likewise, floating point numbers can be declared with the <code>float</code>
builtin; there are two types, differing only in their output format, as
described for the <code>typeset</code> builtin. The output format can be bypassed
by using arithmetic substitution instead of the parameter substitution,
i.e. <code>${``float``}</code> uses the defined format, but <code>$((``float``))</code>
uses a generic floating point format.</p>
<p>Promotion of integer to floating point values is performed where
necessary. In addition, if any operator which requires an integer
(<code>&amp;</code>, <code>|</code>, <code>^</code>, <code>&lt;&lt;</code>, <code>&gt;&gt;</code> and their equivalents with
assignment) is given a floating point argument, it will be silently
rounded towards zero except for <code>~</code> which rounds down.</p>
<p>Users should beware that, in common with many other programming
languages but not software designed for calculation, the evaluation of
an expression in zsh is taken a term at a time and promotion of integers
to floating point does not occur in terms only containing integers. A
typical result of this is that a division such as <code>6/8</code> is truncated, in
this being rounded towards 0. The <code>FORCE_FLOAT</code> shell option can be used
in scripts or functions where floating point evaluation is required
throughout.</p>
<p>Scalar variables can hold integer or floating point values at different
times; there is no memory of the numeric type in this case.</p>
<p>If a variable is first assigned in a numeric context without previously
being declared, it will be implicitly typed as <code>integer</code> or <code>float</code> and
retain that type either until the type is explicitly changed or until
the end of the scope. This can have unforeseen consequences. For
example, in the loop</p>
<div class="example">
<pre><code class="language-example">for (( f = 0; f &lt; 1; f += 0.1 )); do
# use $f
done
</code></pre>
</div>
<p>if <code>f</code> has not already been declared, the first assignment will cause it
to be created as an integer, and consequently the operation <code>f += 0.1</code>
will always cause the result to be truncated to zero, so that the loop
will fail. A simple fix would be to turn the initialization into <code>f = 0.0</code>. It is therefore best to declare numeric variables with explicit
types.</p>
<hr />
<p>This document was generated on <em>February 15, 2020</em> using
<a href="http://www.nongnu.org/texi2html/"><em>texi2html 5.0</em></a>.<br />
Zsh version 5.8, released on February 14, 2020.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="Jobs-_0026-Signals.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="Conditional-Expressions.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="Jobs-_0026-Signals.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="Conditional-Expressions.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>
<!-- Livereload script (if served using the cli tool) -->
<script type="text/javascript">
var socket = new WebSocket("ws://localhost:3000/__livereload");
socket.onmessage = function (event) {
if (event.data === "reload") {
socket.close();
location.reload();
}
};
window.onbeforeunload = function() {
socket.close();
}
</script>
<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>

File diff suppressed because it is too large Load Diff

289
book/Command-Execution.html Normal file
View File

@ -0,0 +1,289 @@
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Command Execution - Zsh Manual</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 -->
</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 "><a href="The-Z-Shell-Manual.html"><strong aria-hidden="true">1.</strong> The Z Shell Manual</a></li><li class="chapter-item expanded "><a href="Introduction.html"><strong aria-hidden="true">2.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="Roadmap.html"><strong aria-hidden="true">3.</strong> Roadmap</a></li><li class="chapter-item expanded "><a href="Invocation.html"><strong aria-hidden="true">4.</strong> Invocation</a></li><li class="chapter-item expanded "><a href="Files.html"><strong aria-hidden="true">5.</strong> Files</a></li><li class="chapter-item expanded "><a href="Shell-Grammar.html"><strong aria-hidden="true">6.</strong> Shell Grammar</a></li><li class="chapter-item expanded "><a href="Redirection.html"><strong aria-hidden="true">7.</strong> Redirection</a></li><li class="chapter-item expanded "><a href="Command-Execution.html" class="active"><strong aria-hidden="true">8.</strong> Command Execution</a></li><li class="chapter-item expanded "><a href="Functions.html"><strong aria-hidden="true">9.</strong> Functions</a></li><li class="chapter-item expanded "><a href="Jobs-_0026-Signals.html"><strong aria-hidden="true">10.</strong> Jobs &amp; Signals</a></li><li class="chapter-item expanded "><a href="Arithmetic-Evaluation.html"><strong aria-hidden="true">11.</strong> Arithmetic Evaluation</a></li><li class="chapter-item expanded "><a href="Conditional-Expressions.html"><strong aria-hidden="true">12.</strong> Conditional Expressions</a></li><li class="chapter-item expanded "><a href="Prompt-Expansion.html"><strong aria-hidden="true">13.</strong> Prompt Expansion</a></li><li class="chapter-item expanded "><a href="Expansion.html"><strong aria-hidden="true">14.</strong> Expansion</a></li><li class="chapter-item expanded "><a href="Parameters.html"><strong aria-hidden="true">15.</strong> Parameters</a></li><li class="chapter-item expanded "><a href="Options.html"><strong aria-hidden="true">16.</strong> Options</a></li><li class="chapter-item expanded "><a href="Shell-Builtin-Commands.html"><strong aria-hidden="true">17.</strong> Shell Builtin Commands</a></li><li class="chapter-item expanded "><a href="Zsh-Line-Editor.html"><strong aria-hidden="true">18.</strong> Zsh Line Editor</a></li><li class="chapter-item expanded "><a href="Completion-Widgets.html"><strong aria-hidden="true">19.</strong> Completion Widgets</a></li><li class="chapter-item expanded "><a href="Completion-System.html"><strong aria-hidden="true">20.</strong> Completion System</a></li><li class="chapter-item expanded "><a href="Completion-Using-compctl.html"><strong aria-hidden="true">21.</strong> Completion Using compctl</a></li><li class="chapter-item expanded "><a href="Zsh-Modules.html"><strong aria-hidden="true">22.</strong> Zsh Modules</a></li><li class="chapter-item expanded "><a href="Calendar-Function-System.html"><strong aria-hidden="true">23.</strong> Calendar Function System</a></li><li class="chapter-item expanded "><a href="TCP-Function-System.html"><strong aria-hidden="true">24.</strong> TCP Function System</a></li><li class="chapter-item expanded "><a href="Zftp-Function-System.html"><strong aria-hidden="true">25.</strong> Zftp Function System</a></li><li class="chapter-item expanded "><a href="User-Contributions.html"><strong aria-hidden="true">26.</strong> User Contributions</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>
</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 Manual</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" name="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="#8-command-execution">8 Command Execution</a></li>
</ul>
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<p><span id="Command-Execution"></span>
<span id="Command-Execution-1"></span></p>
<h1 id="8-command-execution"><a class="header" href="#8-command-execution">8 Command Execution</a></h1>
<p><span id="index-command-execution"></span>
<span id="index-execution_002c-of-commands"></span>
<span id="index-command-not-found_002c-handling-of"></span>
<span id="index-command_005fnot_005ffound_005fhandler"></span></p>
<p>If a command name contains no slashes, the shell attempts to locate it.
If there exists a shell function by that name, the function is invoked
as described in <a href="Functions.html#Functions">Functions</a>. If there exists a
shell builtin by that name, the builtin is invoked.</p>
<p><span id="index-path_002c-use-of"></span></p>
<p>Otherwise, the shell searches each element of <code>$path</code> for a search is
unsuccessful, the shell prints an error message and returns a nonzero
exit status.</p>
<p>and the file is not a directory, it is assumed to be a shell script.
<code>/bin/sh</code> is spawned to execute it. If the program is a file beginning
with <code>#!</code>, the remainder of the first line specifies an interpreter
for the program. The shell will execute the specified interpreter on
operating systems that do</p>
<p>If no external command is found but a function
<code>command_not_found_handler</code> exists the shell executes this function with
all command line arguments. The return status of the function becomes
the status of the command. If the function wishes to mimic the behaviour
of the shell when the command is not found, it should print the message
<code>command not found:</code> <code>cmd</code> to standard error and return status 127.
Note that the handler is executed in a subshell forked to execute an
external command, hence changes to directories, shell parameters, etc.
have no effect on the main shell.</p>
<hr />
<p>This document was generated on <em>February 15, 2020</em> using
<a href="http://www.nongnu.org/texi2html/"><em>texi2html 5.0</em></a>.<br />
Zsh version 5.8, released on February 14, 2020.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="Redirection.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="Functions.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="Redirection.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="Functions.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>
<!-- Livereload script (if served using the cli tool) -->
<script type="text/javascript">
var socket = new WebSocket("ws://localhost:3000/__livereload");
socket.onmessage = function (event) {
if (event.data === "reload") {
socket.close();
location.reload();
}
};
window.onbeforeunload = function() {
socket.close();
}
</script>
<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>

4908
book/Completion-System.html Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,979 @@
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Completion Using compctl - Zsh Manual</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 -->
</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 "><a href="The-Z-Shell-Manual.html"><strong aria-hidden="true">1.</strong> The Z Shell Manual</a></li><li class="chapter-item expanded "><a href="Introduction.html"><strong aria-hidden="true">2.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="Roadmap.html"><strong aria-hidden="true">3.</strong> Roadmap</a></li><li class="chapter-item expanded "><a href="Invocation.html"><strong aria-hidden="true">4.</strong> Invocation</a></li><li class="chapter-item expanded "><a href="Files.html"><strong aria-hidden="true">5.</strong> Files</a></li><li class="chapter-item expanded "><a href="Shell-Grammar.html"><strong aria-hidden="true">6.</strong> Shell Grammar</a></li><li class="chapter-item expanded "><a href="Redirection.html"><strong aria-hidden="true">7.</strong> Redirection</a></li><li class="chapter-item expanded "><a href="Command-Execution.html"><strong aria-hidden="true">8.</strong> Command Execution</a></li><li class="chapter-item expanded "><a href="Functions.html"><strong aria-hidden="true">9.</strong> Functions</a></li><li class="chapter-item expanded "><a href="Jobs-_0026-Signals.html"><strong aria-hidden="true">10.</strong> Jobs &amp; Signals</a></li><li class="chapter-item expanded "><a href="Arithmetic-Evaluation.html"><strong aria-hidden="true">11.</strong> Arithmetic Evaluation</a></li><li class="chapter-item expanded "><a href="Conditional-Expressions.html"><strong aria-hidden="true">12.</strong> Conditional Expressions</a></li><li class="chapter-item expanded "><a href="Prompt-Expansion.html"><strong aria-hidden="true">13.</strong> Prompt Expansion</a></li><li class="chapter-item expanded "><a href="Expansion.html"><strong aria-hidden="true">14.</strong> Expansion</a></li><li class="chapter-item expanded "><a href="Parameters.html"><strong aria-hidden="true">15.</strong> Parameters</a></li><li class="chapter-item expanded "><a href="Options.html"><strong aria-hidden="true">16.</strong> Options</a></li><li class="chapter-item expanded "><a href="Shell-Builtin-Commands.html"><strong aria-hidden="true">17.</strong> Shell Builtin Commands</a></li><li class="chapter-item expanded "><a href="Zsh-Line-Editor.html"><strong aria-hidden="true">18.</strong> Zsh Line Editor</a></li><li class="chapter-item expanded "><a href="Completion-Widgets.html"><strong aria-hidden="true">19.</strong> Completion Widgets</a></li><li class="chapter-item expanded "><a href="Completion-System.html"><strong aria-hidden="true">20.</strong> Completion System</a></li><li class="chapter-item expanded "><a href="Completion-Using-compctl.html" class="active"><strong aria-hidden="true">21.</strong> Completion Using compctl</a></li><li class="chapter-item expanded "><a href="Zsh-Modules.html"><strong aria-hidden="true">22.</strong> Zsh Modules</a></li><li class="chapter-item expanded "><a href="Calendar-Function-System.html"><strong aria-hidden="true">23.</strong> Calendar Function System</a></li><li class="chapter-item expanded "><a href="TCP-Function-System.html"><strong aria-hidden="true">24.</strong> TCP Function System</a></li><li class="chapter-item expanded "><a href="Zftp-Function-System.html"><strong aria-hidden="true">25.</strong> Zftp Function System</a></li><li class="chapter-item expanded "><a href="User-Contributions.html"><strong aria-hidden="true">26.</strong> User Contributions</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>
</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 Manual</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" name="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="#21-completion-using-compctl">21 Completion Using compctl</a>
<ul>
<li><a href="#211-types-of-completion">21.1 Types of completion</a></li>
<li><a href="#212-description">21.2 Description</a></li>
<li><a href="#213-command-flags">21.3 Command Flags</a></li>
<li><a href="#214-option-flags">21.4 Option Flags</a>
<ul>
<li><a href="#2141-simple-flags">21.4.1 Simple Flags</a></li>
<li><a href="#2142-flags-with-arguments">21.4.2 Flags with Arguments</a></li>
<li><a href="#2143-control-flags">21.4.3 Control Flags</a></li>
</ul>
</li>
<li><a href="#215-alternative-completion">21.5 Alternative Completion</a></li>
<li><a href="#216-extended-completion">21.6 Extended Completion</a></li>
<li><a href="#217-example">21.7 Example</a></li>
</ul>
</li>
</ul>
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<p><span id="Completion-Using-compctl"></span>
<span id="Completion-Using-compctl-1"></span></p>
<h1 id="21-completion-using-compctl"><a class="header" href="#21-completion-using-compctl">21 Completion Using compctl</a></h1>
<p><span id="index-completion_002c-programmable-2"></span>
<span id="index-completion_002c-controlling-2"></span></p>
<hr />
<p><span id="Types-of-completion"></span></p>
<h2 id="211-types-of-completion"><a class="header" href="#211-types-of-completion">21.1 Types of completion</a></h2>
<p>This version of zsh has two ways of performing completion of words on
the command line. New users of the shell may prefer to use the newer and
more powerful system based on shell functions; this is described in
<a href="Completion-System.html#Completion-System">Completion System</a>, and the
basic shell mechanisms which support it are described in <a href="Completion-Widgets.html#Completion-Widgets">Completion
Widgets</a>. This chapter
describes the older <code>compctl</code> command.</p>
<hr />
<p><span id="Description-7"></span></p>
<h2 id="212-description"><a class="header" href="#212-description">21.2 Description</a></h2>
<p><span id="index-compctl"></span></p>
<p><code>compctl</code> [ <code>-CDT</code> ] <code>options</code> [ <code>command</code> ... ]</p>
<p><code>compctl </code>[ <code>-CDT</code> ] <code>options</code> [ <code>-x</code> <code>pattern</code> <code>options</code> <code>-</code> ...
<code>-``-</code> ]</p>
<p><code>        </code>[ <code>+</code> <code>options</code> [ <code>-x</code> ... <code>-``-</code> ] ... [<code>+</code>] ] [
<code>command</code> ... ]</p>
<p><code>compctl</code> <code>-M</code> <code>match-specs</code> ...</p>
<p><code>compctl</code> <code>-L</code> [ <code>-CDTM</code> ] [ <code>command</code> ... ]</p>
<p><code>compctl</code> <code>+</code> <code>command</code> ...</p>
<p>Control the editors completion behavior according to the supplied set
of <code>options</code>. Various editing commands, notably
<code>expand-or-complete-word</code>, usually bound to tab, will attempt to
complete a word typed by the user, while others, notably
<code>delete-char-or-list</code>, usually bound to ^D in EMACS editing mode, list
the possibilities; <code>compctl</code> controls what those possibilities are. They
may for example be filenames (the most common case, and hence the
default), shell variables, or words from a user-specified list.</p>
<hr />
<p><span id="Command-Flags"></span> <span id="Command-Flags-1"></span></p>
<h2 id="213-command-flags"><a class="header" href="#213-command-flags">21.3 Command Flags</a></h2>
<p>Completion of the arguments of a command may be different for each
command or may use the default. The behavior when completing the command
word itself may also be separately specified. These correspond to the
following flags and arguments, all of which (except for <code>-L</code>) may be
combined with any combination of the <code>options</code> described subsequently in
<a href="#Option-Flags">Option Flags</a>:</p>
<ul>
<li>
<p><code>command</code> ...<br />
controls completion for the named commands, which must be listed
last on the command line. If completion is attempted for a command
with a pathname containing slashes and no completion definition is
found, the search is retried with the last pathname component. If
the command starts with a <code>=</code>, completion is tried with the pathname
of the command.</p>
<p>Any of the <code>command</code> strings may be patterns of the form normally
used for filename generation. These should be quoted to protect them
from immediate expansion; for example the command string <code>foo*</code>
arranges for completion of the words of any command beginning with
<code>foo</code>. When completion is attempted, all pattern completions are
tried in the reverse order of their definition until one matches. By
default, completion then proceeds as normal, i.e. the shell will try
to generate more matches for the specific command on the command
line; this can be overridden by including <code>-tn</code> in the flags for the
pattern completion.</p>
<p>Note that aliases are expanded before the command name is determined
unless the <code>COMPLETE_ALIASES</code> option is set. Commands may not be
combined with the <code>-C</code>, <code>-D</code> or <code>-T</code> flags.</p>
</li>
<li>
<p><code>-C</code><br />
controls completion when the command word itself is being completed.
If no <code>compctl -C</code> command has been issued, the names of any as
aliases or functions) are completed.</p>
</li>
<li>
<p><code>-D</code><br />
controls default completion behavior for the arguments of commands
not assigned any special behavior. If no <code>compctl -D</code> command has
been issued, filenames are completed.</p>
</li>
<li>
<p><code>-T</code><br />
supplies completion flags to be used before any other processing is
done, even before processing for <code>compctl</code>s defined for specific
commands. This is especially useful when combined with extended
completion (the <code>-x</code> flag, see <a href="#Extended-Completion">Extended
Completion</a> below). Using this flag you can
define default behavior which will apply to all commands without
exception, or you can alter the standard behavior for all commands.
For example, if your access to the user database is too slow and/or
it contains too many users (so that completion after <code>~</code> is too
slow to be usable), you can use</p>
<div class="example">
<pre><code class="language-example">compctl -T -x 's[~] C[0,[^/]#]' -k friends -S/ -tn
</code></pre>
</div>
<p>to complete the strings in the array <code>friends</code> after a <code>~</code>. The
<code>C[``...``]</code> argument is necessary so that this form of
<code>~</code>-completion is not tried after the directory name is finished.</p>
</li>
<li>
<p><code>-L</code><br />
<em>no argument</em><br />
If no argument is given, <code>compctl</code> lists all defined completions in
an abbreviated form; with a list of <code>options</code>, all completions with
those flags set (not counting extended completion) are listed.</p>
</li>
</ul>
<p>If the <code>+</code> flag is alone and followed immediately by the <code>command</code> list,
the completion behavior for all the commands in the list is reset to the
default. In other words, completion will subsequently use the options
specified by the <code>-D</code> flag.</p>
<p>The form with <code>-M</code> as the first and only option defines global matching
specifications (see <a href="Completion-Widgets.html#Completion-Matching-Control">Completion Matching
Control</a>). The
match specifications given will be used for every completion attempt
(only when using <code>compctl</code>, not with the new completion system) and are
tried in the order in which they are defined until one generates at
least one match. E.g.:</p>
<div class="example">
<pre><code class="language-example">compctl -M '' 'm:{a-zA-Z}={A-Za-z}'
</code></pre>
</div>
<p>This will first try completion without any global match specifications
(the empty string) and, if that generates no matches, will try case
insensitive completion.</p>
<hr />
<p><span id="Option-Flags"></span> <span id="Option-Flags-1"></span></p>
<h2 id="214-option-flags"><a class="header" href="#214-option-flags">21.4 Option Flags</a></h2>
<p>[ <code>-fcFBdeaRGovNAIOPZEnbjrzu/12</code> ]</p>
<p>[ <code>-k</code> <code>array</code> ] [ <code>-g</code> <code>globstring</code> ] [ <code>-s</code> <code>subststring</code> ]</p>
<p>[ <code>-K</code> <code>function</code> ]</p>
<p>[ <code>-Q</code> ] [ <code>-P</code> <code>prefix</code> ] [ <code>-S</code> <code>suffix</code> ]</p>
<p>[ <code>-W</code> <code>file-prefix</code> ] [ <code>-H</code> <code>num pattern</code> ]</p>
<p>[ <code>-q</code> ] [ <code>-X</code> <code>explanation</code> ] [ <code>-Y</code> <code>explanation</code> ]</p>
<p>[ <code>-y</code> <code>func-or-var</code> ] [ <code>-l</code> <code>cmd</code> ] [ <code>-h</code> <code>cmd</code> ] [ <code>-U</code> ]</p>
<p>[ <code>-t</code> <code>continue</code> ] [ <code>-J</code> <code>name</code> ] [ <code>-V</code> <code>name</code> ]</p>
<p>[ <code>-M</code> <code>match-spec</code> ]</p>
<p>The remaining <code>options</code> specify the type of command arguments to look
for during completion. Any combination of these flags may be specified;
the result is a sorted list of all the possibilities. The options are as
follows.</p>
<hr />
<p><span id="Simple-Flags"></span> <span id="Simple-Flags-1"></span></p>
<h3 id="2141-simple-flags"><a class="header" href="#2141-simple-flags">21.4.1 Simple Flags</a></h3>
<p>These produce completion lists made up by the shell itself:</p>
<ul>
<li>
<p><code>-f</code><br />
Filenames and file system paths.</p>
</li>
<li>
<p><code>-/</code><br />
Just file system paths.</p>
</li>
<li>
<p><code>-c</code><br />
Command names, including aliases, shell functions, builtins and
reserved words.</p>
</li>
<li>
<p><code>-F</code><br />
Function names.</p>
</li>
<li>
<p><code>-B</code><br />
Names of builtin commands.</p>
</li>
<li>
<p><code>-m</code><br />
Names of external commands.</p>
</li>
<li>
<p><code>-w</code><br />
Reserved words.</p>
</li>
<li>
<p><code>-a</code><br />
Alias names.</p>
</li>
<li>
<p><code>-R</code><br />
Names of regular (non-global) aliases.</p>
</li>
<li>
<p><code>-G</code><br />
Names of global aliases.</p>
</li>
<li>
<p><code>-d</code><br />
This can be combined with <code>-F</code>, <code>-B</code>, <code>-w</code>, <code>-a</code>, <code>-R</code> and <code>-G</code> to
get names of disabled functions, builtins, reserved words or
aliases.</p>
</li>
<li>
<p><code>-e</code><br />
This option (to show enabled commands) is in effect by default, but
may be combined with <code>-d</code>; <code>-de</code> in combination with <code>-F</code>, <code>-B</code>,
<code>-w</code>, <code>-a</code>, <code>-R</code> and <code>-G</code> will complete names of functions,
builtins, reserved words or aliases whether or not they are
disabled.</p>
</li>
<li>
<p><code>-o</code><br />
Names of shell options (see <a href="Options.html#Options">Options</a>).</p>
</li>
<li>
<p><code>-v</code><br />
Names of any variable defined in the shell.</p>
</li>
<li>
<p><code>-N</code><br />
Names of scalar (non-array) parameters.</p>
</li>
<li>
<p><code>-A</code><br />
Array names.</p>
</li>
<li>
<p><code>-I</code><br />
Names of integer variables.</p>
</li>
<li>
<p><code>-O</code><br />
Names of read-only variables.</p>
</li>
<li>
<p><code>-p</code><br />
Names of parameters used by the shell (including special
parameters).</p>
</li>
<li>
<p><code>-Z</code><br />
Names of shell special parameters.</p>
</li>
<li>
<p><code>-E</code><br />
Names of environment variables.</p>
</li>
<li>
<p><code>-n</code><br />
Named directories.</p>
</li>
<li>
<p><code>-b</code><br />
Key binding names.</p>
</li>
<li>
<p><code>-j</code><br />
Job names: the first word of the job leaders command line. This is
useful with the <code>kill</code> builtin.</p>
</li>
<li>
<p><code>-r</code><br />
Names of running jobs.</p>
</li>
<li>
<p><code>-z</code><br />
Names of suspended jobs.</p>
</li>
<li>
<p><code>-u</code><br />
User names.</p>
</li>
</ul>
<hr />
<p><span id="Flags-with-Arguments"></span>
<span id="Flags-with-Arguments-1"></span></p>
<h3 id="2142-flags-with-arguments"><a class="header" href="#2142-flags-with-arguments">21.4.2 Flags with Arguments</a></h3>
<p>These have user supplied arguments to determine how the list of
completions is to be made up:</p>
<ul>
<li>
<p><code>-k</code> <code>array</code><br />
Names taken from the elements of <code>$``array</code> (note that the <code>$</code>
does not appear on the command line). Alternatively, the argument
<code>array</code> itself may be a set of space- or comma-separated values in
parentheses, in which any delimiter may be escaped with a backslash;
in this case the argument should be quoted. For example,</p>
<div class="example">
<pre><code class="language-example">compctl -k &quot;(cputime filesize datasize stacksize
coredumpsize resident descriptors)&quot; limit
</code></pre>
</div>
</li>
<li>
<p><code>-g</code> <code>globstring</code><br />
The <code>globstring</code> is expanded using filename globbing; it should be
quoted to protect it from immediate expansion. The resulting
filenames are taken as the possible completions. Use <code>*(/)</code>
instead of <code>*/</code> for directories. The <code>fignore</code> special parameter
is not applied to the resulting files. More than one pattern may be
given separated by blanks. (Note that brace expansion is <em>not</em> part
of globbing. Use the syntax <code>(either|or)</code> to match alternatives.)</p>
</li>
<li>
<p><code>-s</code> <code>subststring</code><br />
The <code>subststring</code> is split into words and these words are than
expanded using all shell expansion mechanisms (see
<a href="Expansion.html#Expansion">Expansion</a>). The resulting words are
taken as possible completions. The <code>fignore</code> special parameter is
not applied to the resulting files. Note that <code>-g</code> is faster for
filenames.</p>
</li>
<li>
<p><code>-K</code> <code>function</code><br />
<span id="index-reply_002c-use-of-2"></span></p>
<p>Call the given function to get the completions. Unless the name
starts with an underscore, the function is passed two arguments: the
prefix and the suffix of the word on which completion is to be
attempted, in other words those characters before the cursor
position, and those from the cursor position onwards. The whole
command line can be accessed with the <code>-c</code> and <code>-l</code> flags of the
<code>read</code> builtin. The function should set the variable <code>reply</code> to an
array containing the completions (one completion per element); note
that <code>reply</code> should not be made local to the function. From such a
function the command line can be accessed with the <code>-c</code> and <code>-l</code>
flags to the <code>read</code> builtin. For example,</p>
<div class="example">
<pre><code class="language-example">function whoson { reply=(`users`); }
compctl -K whoson talk
</code></pre>
</div>
<p>completes only logged-on users after <code>talk</code>. Note that <code>whoson</code>
must return an array, so <code>reply=users</code> would be incorrect.</p>
</li>
<li>
<p><code>-H</code> <code>num pattern</code><br />
The possible completions are taken from the last <code>num</code> history
lines. Only words matching <code>pattern</code> are taken. If <code>num</code> is zero or
negative the whole history is searched and if <code>pattern</code> is the empty
string all words are taken (as with <code>*</code>). A typical use is</p>
<div class="example">
<pre><code class="language-example">compctl -D -f + -H 0 ''
</code></pre>
</div>
<p>which forces completion to look back in the history list for a word
if no filename matches.</p>
</li>
</ul>
<hr />
<p><span id="Control-Flags"></span> <span id="Control-Flags-1"></span></p>
<h3 id="2143-control-flags"><a class="header" href="#2143-control-flags">21.4.3 Control Flags</a></h3>
<p>These do not directly specify types of name to be completed, but
manipulate the options that do:</p>
<ul>
<li>
<p><code>-Q</code><br />
This instructs the shell not to quote any metacharacters in the
possible completions. Normally the results of a completion are
inserted into the command line with any metacharacters quoted so
that they are interpreted as normal characters. This is appropriate
for filenames and ordinary strings. However, for special effects,
such as inserting a backquoted expression from a completion array
(<code>-k</code>) so that the expression will not be evaluated until the
complete line is executed, this option must be used.</p>
</li>
<li>
<p><code>-P</code> <code>prefix</code><br />
The <code>prefix</code> is inserted just before the completed string; any
initial part already typed will be completed and the whole <code>prefix</code>
ignored for completion purposes. For example,</p>
<div class="example">
<pre><code class="language-example">compctl -j -P &quot;%&quot; kill
</code></pre>
</div>
<p>inserts a % after the kill command and then completes job names.</p>
</li>
<li>
<p><code>-S</code> <code>suffix</code><br />
When a completion is found the <code>suffix</code> is inserted after the
completed string. In the case of menu completion the suffix is
inserted immediately, but it is still possible to cycle through the
list of completions by repeatedly hitting the same key.</p>
</li>
<li>
<p><code>-W</code> <code>file-prefix</code><br />
With directory <code>file-prefix</code>: for command, file, directory and
globbing completion (options <code>-c</code>, <code>-f</code>, <code>-/</code>, <code>-g</code>), the file
prefix is implicitly added in front of the completion. For example,</p>
<div class="example">
<pre><code class="language-example">compctl -/ -W ~/Mail maildirs
</code></pre>
</div>
<p>completes any subdirectories to any depth beneath the directory
<code>~/Mail</code>, although that prefix does not appear on the command line.
The <code>file-prefix</code> may also be of the form accepted by the <code>-k</code> flag,
i.e. the name of an array or a literal list in parenthesis. In this
case all the directories in the list will be searched for possible
completions.</p>
</li>
<li>
<p><code>-q</code><br />
If used with a suffix as specified by the <code>-S</code> option, this causes
the suffix to be removed if the next character typed is a blank or
does not insert anything or if the suffix consists of only one
character and the next character typed is the same character; this
the same rule used for the <code>AUTO_REMOVE_SLASH</code> option. The option is
most useful for list separators (comma, colon, etc.).</p>
</li>
<li>
<p><code>-l</code> <code>cmd</code><br />
This option restricts the range of command line words that are
considered to be arguments. If combined with one of the extended
completion patterns <code>p[</code>...<code>]</code>, <code>r[</code>...<code>]</code>, or <code>R[</code>...<code>]</code> (see
<a href="#Extended-Completion">Extended Completion</a> below) the range is
restricted to the range of arguments specified in the brackets.
Completion is then performed as if these had been given as arguments
to the <code>cmd</code> supplied with the option. If the <code>cmd</code> string is empty
the first word in the range is instead taken as the command name,
and command name completion performed on the first word in the
range. For example,</p>
<div class="example">
<pre><code class="language-example">compctl -x 'r[-exec,;]' -l '' -- find
</code></pre>
</div>
<p>completes arguments between <code>-exec</code> and the following <code>;</code> (or
the end of the command line if there is no such string) as if they
were a separate command line.</p>
</li>
<li>
<p><code>-h</code> <code>cmd</code><br />
Normally zsh completes quoted strings as a whole. With this option,
completion can be done separately on different parts of such
strings. It works like the <code>-l</code> option but makes the completion code
work on the parts of the current word that are separated by spaces.
These parts are completed as if they were arguments to the given
<code>cmd</code>. If <code>cmd</code> is the empty string, the first part is completed as
a command name, as with <code>-l</code>.</p>
</li>
<li>
<p><code>-U</code><br />
Use the whole list of possible completions, whether or not they
actually match the word on the command line. The word typed so far
will be deleted. This is most useful with a function (given by the
<code>-K</code> option) which can examine the word components passed to it (or
via the <code>read</code> builtins <code>-c</code> and <code>-l</code> flags) and use its own
criteria to decide what matches. If there is no completion, the
original word is retained. Since the produced possible completions
seldom have interesting common prefixes and suffixes, menu
completion is started immediately if <code>AUTO_MENU</code> is set and this
flag is used.</p>
</li>
<li>
<p><code>-y</code> <code>func-or-var</code><br />
<span id="index-reply_002c-use-of-3"></span></p>
<p>The list provided by <code>func-or-var</code> is displayed instead of the list
of completions whenever a listing is required; the actual
completions to be inserted are not affected. It can be provided in
two ways. Firstly, if <code>func-or-var</code> begins with a <code>$</code> it defines a
variable, or if it begins with a left parenthesis a literal array,
which contains the list. A variable may have been set by a call to a
function using the <code>-K</code> option. Otherwise it contains the name of a
function which will be executed to create the list. The function
will be passed as an argument list all matching completions,
including prefixes and suffixes expanded in full, and should set the
array <code>reply</code> to the result. In both cases, the display list will
only be retrieved after a complete list of matches has been created.</p>
<p>Note that the returned list does not have to correspond, even in
length, to the original set of matches, and may be passed as a
scalar instead of an array. No special formatting of characters is
performed on the output in this case; in particular, newlines are
printed literally and if they appear output in columns is
suppressed.</p>
</li>
<li>
<p><code>-X</code> <code>explanation</code><br />
Print <code>explanation</code> when trying completion on the current set of
options. A <code>%n</code> in this string is replaced by the number of
matches that were added for this explanation string. The explanation
only appears if completion was tried and there was no unique match,
or when listing completions. Explanation strings will be listed
together with the matches of the group specified together with the
<code>-X</code> option (using the <code>-J</code> or <code>-V</code> option). If the same explanation
string is given to multiple <code>-X</code> options, the string appears only
once (for each group) and the number of matches shown for the <code>%n</code>
is the total number of all matches for each of these uses. In any
case, the explanation string will only be shown if there was at
least one match added for the explanation string.</p>
<p>The sequences <code>%B</code>, <code>%b</code>, <code>%S</code>, <code>%s</code>, <code>%U</code>, and <code>%u</code> specify output
attributes (bold, standout, and underline), <code>%F</code>, <code>%f</code>, <code>%K</code>, <code>%k</code>
specify foreground and background colours, and <code>%{``...``%}</code> can be
used to include literal escape sequences as in prompts.</p>
</li>
<li>
<p><code>-Y</code> <code>explanation</code><br />
Identical to <code>-X</code>, except that the <code>explanation</code> first undergoes
expansion following the usual rules for strings in double quotes.
The expansion will be carried out after any functions are called for
the <code>-K</code> or <code>-y</code> options, allowing them to set variables.</p>
</li>
<li>
<p><code>-t</code> <code>continue</code><br />
The <code>continue</code>-string contains a character that specifies which set
of completion flags should be used next. It is useful:</p>
<p>(i) With <code>-T</code>, or when trying a list of pattern completions, when
<code>compctl</code> would usually continue with ordinary processing after
finding matches; this can be suppressed with <code>-tn</code>.</p>
<p>(ii) With a list of alternatives separated by <code>+</code>, when <code>compctl</code>
would normally stop when one of the alternatives generates matches.
It can be forced to consider the next set of completions by adding
<code>-t+</code> to the flags of the alternative before the <code>+</code>.</p>
<p>(iii) In an extended completion list (see below), when <code>compctl</code>
would normally continue until a set of conditions succeeded, then
use only the immediately following flags. With <code>-t-</code>, <code>compctl</code>
will continue trying extended completions after the next <code>-</code>; with
<code>-tx</code> it will attempt completion with the default flags, in other
words those before the <code>-x</code>.</p>
</li>
<li>
<p><code>-J</code> <code>name</code><br />
This gives the name of the group the matches should be placed in.
Groups are listed and sorted separately; likewise, menu completion
will offer the matches in the groups in the order in which the
groups were defined. If no group name is explicitly given, the
matches are stored in a group named <code>default</code>. The first time a
group name is encountered, a group with that name is created. After
that all matches with the same group name are stored in that group.</p>
<p>This can be useful with non-exclusive alternative completions. For
example, in</p>
<div class="example">
<pre><code class="language-example">compctl -f -J files -t+ + -v -J variables foo
</code></pre>
</div>
<p>both files and variables are possible completions, as the <code>-t+</code>
forces both sets of alternatives before and after the <code>+</code> to be
considered at once. Because of the <code>-J</code> options, however, all files
are listed before all variables.</p>
</li>
<li>
<p><code>-V</code> <code>name</code><br />
Like <code>-J</code>, but matches within the group will not be sorted in
listings nor in menu completion. These unsorted groups are in a
different name space from the sorted ones, so groups defined as <code>-J files</code> and <code>-V files</code> are distinct.</p>
</li>
<li>
<p><code>-1</code><br />
If given together with the <code>-V</code> option, makes only consecutive
duplicates in the group be removed. Note that groups with and
without this flag are in different name spaces.</p>
</li>
<li>
<p><code>-2</code><br />
If given together with the <code>-J</code> or <code>-V</code> option, makes all duplicates
be kept. Again, groups with and without this flag are in different
name spaces.</p>
</li>
<li>
<p><code>-M</code> <code>match-spec</code><br />
This defines additional matching control specifications that should
be used only when testing words for the list of flags this flag
appears in. The format of the <code>match-spec</code> string is described in
<a href="Completion-Widgets.html#Completion-Matching-Control">Completion Matching
Control</a>.</p>
</li>
</ul>
<hr />
<p><span id="Alternative-Completion"></span>
<span id="Alternative-Completion-1"></span></p>
<h2 id="215-alternative-completion"><a class="header" href="#215-alternative-completion">21.5 Alternative Completion</a></h2>
<p><code>compctl</code> [ <code>-CDT</code> ] <code>options</code> <code>+</code> <code>options</code> [ <code>+</code> ... ] [ <code>+</code> ]
<code>command</code> ...</p>
<p>The form with <code>+</code> specifies alternative options. Completion is tried
with the options before the first <code>+</code>. If this produces no matches
completion is tried with the flags after the <code>+</code> and so on. If there
are no flags after the last <code>+</code> and a match has not been found up to
that point, default completion is tried. If the list of flags contains a
<code>-t</code> with a <code>+</code> character, the next list of flags is used even if the
current list produced matches.</p>
<hr />
<p><span id="Extended-Completion"></span></p>
<p>Additional options are available that restrict completion to some part
of the command line; this is referred to as extended completion.</p>
<p><span id="Extended-Completion-1"></span></p>
<h2 id="216-extended-completion"><a class="header" href="#216-extended-completion">21.6 Extended Completion</a></h2>
<p><code>compctl </code>[ <code>-CDT</code> ] <code>options</code> <code>-x</code> <code>pattern</code> <code>options</code> <code>-</code> ...
<code>-``-</code></p>
<p><code>        </code>[ <code>command</code> ... ]</p>
<p><code>compctl </code>[ <code>-CDT</code> ] <code>options</code> [ <code>-x</code> <code>pattern</code> <code>options</code> <code>-</code> ...
<code>-``-</code> ]</p>
<p><code>        </code>[ <code>+</code> <code>options</code> [ <code>-x</code> ... <code>-``-</code> ] ... [<code>+</code>] ] [
<code>command</code> ... ]</p>
<p>The form with <code>-x</code> specifies extended completion for the commands
given; as shown, it may be combined with alternative completion using
<code>+</code>. Each <code>pattern</code> is examined in turn; when a match is found, the
corresponding <code>options</code>, as described in <a href="#Option-Flags">Option Flags</a>
above, are used to generate possible completions. If no <code>pattern</code>
matches, the <code>options</code> given before the <code>-x</code> are used.</p>
<p>Note that each pattern should be supplied as a single argument and
should be quoted to prevent expansion of metacharacters by the shell.</p>
<p>A <code>pattern</code> is built of sub-patterns separated by commas; it matches if
at least one of these sub-patterns matches (they are ored). These
sub-patterns are in turn composed of other sub-patterns separated by
white spaces which match if all of the sub-patterns match (they are
anded). An element of the sub-patterns is of the form
<code>c``[</code>...<code>][</code>...<code>]</code>, where the pairs of brackets may be repeated as
often as necessary, and matches if any of the sets of brackets match (an
or). The example below makes this clearer.</p>
<p>The elements may be any of the following:</p>
<ul>
<li>
<p><code>s[``string``]</code>...<br />
Matches if the current word on the command line starts with one of
the strings given in brackets. The <code>string</code> is not removed and is
not part of the completion.</p>
</li>
<li>
<p><code>S[``string``]</code>...<br />
Like <code>s[``string``]</code> except that the <code>string</code> is part of the
completion.</p>
</li>
<li>
<p><code>p[``from``,``to``]</code>...<br />
Matches if the number of the current word is between one of the
<code>from</code> and <code>to</code> pairs inclusive. The comma and <code>to</code> are optional;
<code>to</code> defaults to the same value as <code>from</code>. The numbers may be
negative: <code>-``n</code> refers to the <code>n</code>th last word on the line.</p>
</li>
<li>
<p><code>c[``offset``,``string``]</code>...<br />
Matches if the <code>string</code> matches the word offset by <code>offset</code> from the
current word position. Usually <code>offset</code> will be negative.</p>
</li>
<li>
<p><code>C[``offset``,``pattern``]</code>...<br />
Like <code>c</code> but using pattern matching instead.</p>
</li>
<li>
<p><code>w[``index``,``string``]</code>...<br />
Matches if the word in position <code>index</code> is equal to the
corresponding <code>string</code>. Note that the word count is made after any
alias expansion.</p>
</li>
<li>
<p><code>W[``index``,``pattern``]</code>...<br />
Like <code>w</code> but using pattern matching instead.</p>
</li>
<li>
<p><code>n[``index``,``string``]</code>...<br />
Matches if the current word contains <code>string</code>. Anything up to and
including the <code>index</code>th occurrence of this string will not be
considered part of the completion, but the rest will. <code>index</code> may be
negative to count from the end: in most cases, <code>index</code> will be 1 or
-1. For example,</p>
<div class="example">
<pre><code class="language-example">compctl -s '`users`' -x 'n[1,@]' -k hosts -- talk
</code></pre>
</div>
<p>will usually complete usernames, but if you insert an <code>@</code> after the
name, names from the array <code>hosts</code> (assumed to contain hostnames,
though you must make the array yourself) will be completed. Other
commands such as <code>rcp</code> can be handled similarly.</p>
</li>
<li>
<p><code>N[``index``,``string``]</code>...<br />
Like <code>n</code> except that the string will be taken as a character class.
Anything up to and including the <code>index</code>th occurrence of any of the
characters in <code>string</code> will not be considered part of the
completion.</p>
</li>
<li>
<p><code>m[``min``,``max``]</code>...<br />
Matches if the total number of words lies between <code>min</code> and <code>max</code>
inclusive.</p>
</li>
<li>
<p><code>r[``str1``,``str2``]</code>...<br />
Matches if the cursor is after a word with prefix <code>str1</code>. If there
is also a word with prefix <code>str2</code> on the command line after the one
matched by <code>str1</code> it matches only if the cursor is before this word.
If the comma and <code>str2</code> are omitted, it matches if the cursor is
after a word with prefix <code>str1</code>.</p>
</li>
<li>
<p><code>R[``str1``,``str2``]</code>...<br />
Like <code>r</code> but using pattern matching instead.</p>
</li>
<li>
<p><code>q[``str``]</code>...<br />
Matches the word currently being completed is in single quotes and
the <code>str</code> begins with the letter s, or if completion is done in
double quotes and <code>str</code> starts with the letter d, or if completion
is done in backticks and <code>str</code> starts with a b.</p>
</li>
</ul>
<hr />
<p><span id="Example"></span> <span id="Example-3"></span></p>
<h2 id="217-example"><a class="header" href="#217-example">21.7 Example</a></h2>
<div class="example">
<pre><code class="language-example">compctl -u -x 's[+] c[-1,-f],s[-f+]' \
-g '~/Mail/*(:t)' - 's[-f],c[-1,-f]' -f -- mail
</code></pre>
</div>
<p>This is to be interpreted as follows:</p>
<p>If the current command is <code>mail</code>, then</p>
<blockquote>
<p>if ((the current word begins with <code>+</code> and the previous word is <code>-f</code>)
or (the current word begins with <code>-f+</code>)), then complete the
non-directory part (the <code>:t</code> glob modifier) of files in the
directory <code>~/Mail</code>; else</p>
<p>if the current word begins with <code>-f</code> or the previous word was <code>-f</code>,
then complete any file; else</p>
<p>complete user names.</p>
</blockquote>
<hr />
<p>This document was generated on <em>February 15, 2020</em> using
<a href="http://www.nongnu.org/texi2html/"><em>texi2html 5.0</em></a>.<br />
Zsh version 5.8, released on February 14, 2020.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="Completion-System.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="Zsh-Modules.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="Completion-System.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="Zsh-Modules.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>
<!-- Livereload script (if served using the cli tool) -->
<script type="text/javascript">
var socket = new WebSocket("ws://localhost:3000/__livereload");
socket.onmessage = function (event) {
if (event.data === "reload") {
socket.close();
location.reload();
}
};
window.onbeforeunload = function() {
socket.close();
}
</script>
<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>

1389
book/Completion-Widgets.html Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,533 @@
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Conditional Expressions - Zsh Manual</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 -->
</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 "><a href="The-Z-Shell-Manual.html"><strong aria-hidden="true">1.</strong> The Z Shell Manual</a></li><li class="chapter-item expanded "><a href="Introduction.html"><strong aria-hidden="true">2.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="Roadmap.html"><strong aria-hidden="true">3.</strong> Roadmap</a></li><li class="chapter-item expanded "><a href="Invocation.html"><strong aria-hidden="true">4.</strong> Invocation</a></li><li class="chapter-item expanded "><a href="Files.html"><strong aria-hidden="true">5.</strong> Files</a></li><li class="chapter-item expanded "><a href="Shell-Grammar.html"><strong aria-hidden="true">6.</strong> Shell Grammar</a></li><li class="chapter-item expanded "><a href="Redirection.html"><strong aria-hidden="true">7.</strong> Redirection</a></li><li class="chapter-item expanded "><a href="Command-Execution.html"><strong aria-hidden="true">8.</strong> Command Execution</a></li><li class="chapter-item expanded "><a href="Functions.html"><strong aria-hidden="true">9.</strong> Functions</a></li><li class="chapter-item expanded "><a href="Jobs-_0026-Signals.html"><strong aria-hidden="true">10.</strong> Jobs &amp; Signals</a></li><li class="chapter-item expanded "><a href="Arithmetic-Evaluation.html"><strong aria-hidden="true">11.</strong> Arithmetic Evaluation</a></li><li class="chapter-item expanded "><a href="Conditional-Expressions.html" class="active"><strong aria-hidden="true">12.</strong> Conditional Expressions</a></li><li class="chapter-item expanded "><a href="Prompt-Expansion.html"><strong aria-hidden="true">13.</strong> Prompt Expansion</a></li><li class="chapter-item expanded "><a href="Expansion.html"><strong aria-hidden="true">14.</strong> Expansion</a></li><li class="chapter-item expanded "><a href="Parameters.html"><strong aria-hidden="true">15.</strong> Parameters</a></li><li class="chapter-item expanded "><a href="Options.html"><strong aria-hidden="true">16.</strong> Options</a></li><li class="chapter-item expanded "><a href="Shell-Builtin-Commands.html"><strong aria-hidden="true">17.</strong> Shell Builtin Commands</a></li><li class="chapter-item expanded "><a href="Zsh-Line-Editor.html"><strong aria-hidden="true">18.</strong> Zsh Line Editor</a></li><li class="chapter-item expanded "><a href="Completion-Widgets.html"><strong aria-hidden="true">19.</strong> Completion Widgets</a></li><li class="chapter-item expanded "><a href="Completion-System.html"><strong aria-hidden="true">20.</strong> Completion System</a></li><li class="chapter-item expanded "><a href="Completion-Using-compctl.html"><strong aria-hidden="true">21.</strong> Completion Using compctl</a></li><li class="chapter-item expanded "><a href="Zsh-Modules.html"><strong aria-hidden="true">22.</strong> Zsh Modules</a></li><li class="chapter-item expanded "><a href="Calendar-Function-System.html"><strong aria-hidden="true">23.</strong> Calendar Function System</a></li><li class="chapter-item expanded "><a href="TCP-Function-System.html"><strong aria-hidden="true">24.</strong> TCP Function System</a></li><li class="chapter-item expanded "><a href="Zftp-Function-System.html"><strong aria-hidden="true">25.</strong> Zftp Function System</a></li><li class="chapter-item expanded "><a href="User-Contributions.html"><strong aria-hidden="true">26.</strong> User Contributions</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>
</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 Manual</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" name="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="#12-conditional-expressions">12 Conditional Expressions</a></li>
</ul>
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<p><span id="Conditional-Expressions"></span>
<span id="Conditional-Expressions-1"></span></p>
<h1 id="12-conditional-expressions"><a class="header" href="#12-conditional-expressions">12 Conditional Expressions</a></h1>
<p><span id="index-conditional-expressions"></span>
<span id="index-expressions_002c-conditional"></span></p>
<p>A <em>conditional expression</em> is used with the <code>[[</code> compound command to
test attributes of files and to compare strings. Each expression can be
constructed from one or more of the following unary or binary
expressions:</p>
<ul>
<li>
<p><code>-a</code> <code>file</code><br />
true if <code>file</code> exists.</p>
</li>
<li>
<p><code>-b</code> <code>file</code><br />
true if <code>file</code> exists and is a block special file.</p>
</li>
<li>
<p><code>-c</code> <code>file</code><br />
true if <code>file</code> exists and is a character special file.</p>
</li>
<li>
<p><code>-d</code> <code>file</code><br />
true if <code>file</code> exists and is a directory.</p>
</li>
<li>
<p><code>-e</code> <code>file</code><br />
true if <code>file</code> exists.</p>
</li>
<li>
<p><code>-f</code> <code>file</code><br />
true if <code>file</code> exists and is a regular file.</p>
</li>
<li>
<p><code>-g</code> <code>file</code><br />
true if <code>file</code> exists and has its setgid bit set.</p>
</li>
<li>
<p><code>-h</code> <code>file</code><br />
true if <code>file</code> exists and is a symbolic link.</p>
</li>
<li>
<p><code>-k</code> <code>file</code><br />
true if <code>file</code> exists and has its sticky bit set.</p>
</li>
<li>
<p><code>-n</code> <code>string</code><br />
true if length of <code>string</code> is non-zero.</p>
</li>
<li>
<p><code>-o</code> <code>option</code><br />
true if option named <code>option</code> is on. <code>option</code> may be a single
character, in which case it is a single letter option name. (See
<a href="Options.html#Specifying-Options">Specifying Options</a>.)</p>
<p>When no option named <code>option</code> exists, and the <code>POSIX_BUILTINS</code>
option hasnt been set, return 3 with a warning. If that option is
set, return 1 with no warning.</p>
</li>
<li>
<p><code>-p</code> <code>file</code><br />
true if <code>file</code> exists and is a FIFO special file (named pipe).</p>
</li>
<li>
<p><code>-r</code> <code>file</code><br />
true if <code>file</code> exists and is readable by current process.</p>
</li>
<li>
<p><code>-s</code> <code>file</code><br />
true if <code>file</code> exists and has size greater than zero.</p>
</li>
<li>
<p><code>-t</code> <code>fd</code><br />
true if file descriptor number <code>fd</code> is open and associated with a
terminal device. (note: <code>fd</code> is not optional)</p>
</li>
<li>
<p><code>-u</code> <code>file</code><br />
true if <code>file</code> exists and has its setuid bit set.</p>
</li>
<li>
<p><code>-v</code> <code>varname</code><br />
true if shell variable <code>varname</code> is set.</p>
</li>
<li>
<p><code>-w</code> <code>file</code><br />
<code>-x</code> <code>file</code><br />
<code>-z</code> <code>string</code><br />
true if length of <code>string</code> is zero.</p>
</li>
<li>
<p><code>-L</code> <code>file</code><br />
true if <code>file</code> exists and is a symbolic link.</p>
</li>
<li>
<p><code>-O</code> <code>file</code><br />
true if <code>file</code> exists and is owned by the effective user ID of this
process.</p>
</li>
<li>
<p><code>-G</code> <code>file</code><br />
true if <code>file</code> exists and its group matches the effective group ID
of this process.</p>
</li>
<li>
<p><code>-S</code> <code>file</code><br />
true if <code>file</code> exists and is a socket.</p>
</li>
<li>
<p><code>-N</code> <code>file</code><br />
true if <code>file</code> exists and its access time is not newer than its
modification time.</p>
</li>
<li>
<p><code>file1</code> <code>-nt</code> <code>file2</code><br />
true if <code>file1</code> exists and is newer than <code>file2</code>.</p>
</li>
<li>
<p><code>file1</code> <code>-ot</code> <code>file2</code><br />
true if <code>file1</code> exists and is older than <code>file2</code>.</p>
</li>
<li>
<p><code>file1</code> <code>-ef</code> <code>file2</code><br />
true if <code>file1</code> and <code>file2</code> exist and refer to the same file.</p>
</li>
<li>
<p><code>string</code> <code>=</code> <code>pattern</code><br />
<code>string</code> <code>==</code> <code>pattern</code><br />
true if <code>string</code> matches <code>pattern</code>. The two forms are exactly
equivalent. The <code>=</code> form is the traditional shell syntax (and
hence the only one generally used with the <code>test</code> and <code>[</code> builtins);
the <code>==</code> form provides compatibility with other sorts of computer
language.</p>
</li>
<li>
<p><code>string</code> <code>!=</code> <code>pattern</code><br />
true if <code>string</code> does not match <code>pattern</code>.</p>
</li>
<li>
<p><code>string</code> <code>=~</code> <code>regexp</code><br />
true if <code>string</code> matches the regular expression <code>regexp</code>. If the
option <code>RE_MATCH_PCRE</code> is set <code>regexp</code> is tested as a PCRE regular
expression using the <code>zsh/pcre</code> module, else it is tested as a POSIX
extended regular expression using the <code>zsh/regex</code> module. Upon
successful match, some variables will be updated; no variables are
changed if the matching fails.</p>
<p>If the option <code>BASH_REMATCH</code> is not set the scalar parameter <code>MATCH</code>
is set to the substring that matched the pattern and the integer
parameters <code>MBEGIN</code> and <code>MEND</code> to the index of the start and end,
respectively, of the match in <code>string</code>, such that if <code>string</code> is
contained in variable <code>var</code> the expression <code>${var[$MBEGIN,$MEND]}</code>
is identical to <code>$MATCH</code>. The setting of the option <code>KSH_ARRAYS</code>
is respected. Likewise, the array <code>match</code> is set to the substrings
that matched parenthesised subexpressions and the arrays <code>mbegin</code>
and <code>mend</code> to the indices of the start and end positions,
respectively, of the substrings within <code>string</code>. The arrays are not
set if there were no parenthesised subexpressions. For example, if
the string <code>a short string</code> is matched against the regular
expression <code>s(...)t</code>, then (assuming the option <code>KSH_ARRAYS</code> is
not set) <code>MATCH</code>, <code>MBEGIN</code> and <code>MEND</code> are <code>short</code>, <code>3</code> and <code>7</code>,
respectively, while <code>match</code>, <code>mbegin</code> and <code>mend</code> are single entry
arrays containing the strings <code>hor</code>, <code>4</code> and <code>6</code>,
respectively.</p>
<p>If the option <code>BASH_REMATCH</code> is set the array <code>BASH_REMATCH</code> is set
to the substring that matched the pattern followed by the substrings
that matched parenthesised subexpressions within the pattern.</p>
</li>
<li>
<p><code>string1</code> <code>&lt;</code> <code>string2</code><br />
true if <code>string1</code> comes before <code>string2</code> based on ASCII value of
their characters.</p>
</li>
<li>
<p><code>string1</code> <code>&gt;</code> <code>string2</code><br />
true if <code>string1</code> comes after <code>string2</code> based on ASCII value of
their characters.</p>
</li>
<li>
<p><code>exp1</code> <code>-eq</code> <code>exp2</code><br />
true if <code>exp1</code> is numerically equal to <code>exp2</code>. Note that for purely
numeric comparisons use of the <code>((``...``))</code> builtin described in
<a href="Arithmetic-Evaluation.html#Arithmetic-Evaluation">Arithmetic
Evaluation</a> is
more convenient than conditional expressions.</p>
</li>
<li>
<p><code>exp1</code> <code>-ne</code> <code>exp2</code><br />
true if <code>exp1</code> is numerically not equal to <code>exp2</code>.</p>
</li>
<li>
<p><code>exp1</code> <code>-lt</code> <code>exp2</code><br />
true if <code>exp1</code> is numerically less than <code>exp2</code>.</p>
</li>
<li>
<p><code>exp1</code> <code>-gt</code> <code>exp2</code><br />
true if <code>exp1</code> is numerically greater than <code>exp2</code>.</p>
</li>
<li>
<p><code>exp1</code> <code>-le</code> <code>exp2</code><br />
true if <code>exp1</code> is numerically less than or equal to <code>exp2</code>.</p>
</li>
<li>
<p><code>exp1</code> <code>-ge</code> <code>exp2</code><br />
true if <code>exp1</code> is numerically greater than or equal to <code>exp2</code>.</p>
</li>
<li>
<p><code>(</code> <code>exp</code> <code>)</code><br />
true if <code>exp</code> is true.</p>
</li>
<li>
<p><code>!</code> <code>exp</code><br />
true if <code>exp</code> is false.</p>
</li>
<li>
<p><code>exp1</code> <code>&amp;&amp;</code> <code>exp2</code><br />
true if <code>exp1</code> and <code>exp2</code> are both true.</p>
</li>
<li>
<p><code>exp1</code> <code>||</code> <code>exp2</code><br />
true if either <code>exp1</code> or <code>exp2</code> is true.</p>
</li>
</ul>
<p>For compatibility, if there is a single argument that is not
syntactically significant, typically a variable, the condition is
treated as a test for whether the expression expands as a string of
non-zero length. In other words, <code>[[ $var ]]</code> is the same as <code>[[ -n $var ]]</code>. It is recommended that the second, explicit, form be used where
possible.</p>
<p>Normal shell expansion is performed on the <code>file</code>, <code>string</code> and
<code>pattern</code> arguments, but the result of each expansion is constrained to
be a single word, similar to the effect of double quotes.</p>
<p>Filename generation is not performed on any form of argument to
conditions. However, it can be forced in any case where normal shell
expansion is valid and when the option <code>EXTENDED_GLOB</code> is in effect by
using an explicit glob qualifier of the form <code>(#q)</code> at the end of the
string. A normal glob qualifier expression may appear between the <code>q</code>
and the closing parenthesis; if none appears the expression has no
effect beyond causing filename generation. The results of filename
generation are joined together to form a single word, as with the
results of other forms of expansion.</p>
<p>This special use of filename generation is only available with the <code>[[</code>
syntax. If the condition occurs within the <code>[</code> or <code>test</code> builtin
commands then globbing occurs instead as part of normal command line
expansion before the condition is evaluated. In this case it may
generate multiple words which are likely to confuse the syntax of the
test command.</p>
<p>For example,</p>
<div class="example">
<pre><code class="language-example">[[ -n file*(#qN) ]]
</code></pre>
</div>
<p>produces status zero if and only if there is at least one file in the
current directory beginning with the string <code>file</code>. The globbing
qualifier <code>N</code> ensures that the expression is empty if there is no
matching file.</p>
<p>Pattern metacharacters are active for the <code>pattern</code> arguments; the
patterns are the same as those used for filename generation, see
<a href="Expansion.html#Filename-Generation">Filename Generation</a>, but there is
no special behaviour of <code>/</code> nor initial dots, and no glob qualifiers
are allowed.</p>
<p>In each of the above expressions, if <code>file</code> is of the form
<code>/dev/fd/``n</code>, where <code>n</code> is an integer, then the test applied to the
open file whose descriptor number is <code>n</code>, even if the underlying system
does not support the <code>/dev/fd</code> directory.</p>
<p>In the forms which do numeric comparison, the expressions <code>exp</code> undergo
arithmetic expansion as if they were enclosed in <code>$((``...``))</code>.</p>
<p>For example, the following:</p>
<div class="example">
<pre><code class="language-example">[[ ( -f foo || -f bar ) &amp;&amp; $report = y* ]] &amp;&amp; print File exists.
</code></pre>
</div>
<p>tests if either file <code>foo</code> or file <code>bar</code> exists, and if so, if the value
of the parameter <code>report</code> begins with <code>y</code>; if the complete condition
is true, the message <code>File exists.</code> is printed.</p>
<hr />
<p>This document was generated on <em>February 15, 2020</em> using
<a href="http://www.nongnu.org/texi2html/"><em>texi2html 5.0</em></a>.<br />
Zsh version 5.8, released on February 14, 2020.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="Arithmetic-Evaluation.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="Prompt-Expansion.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="Arithmetic-Evaluation.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="Prompt-Expansion.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>
<!-- Livereload script (if served using the cli tool) -->
<script type="text/javascript">
var socket = new WebSocket("ws://localhost:3000/__livereload");
socket.onmessage = function (event) {
if (event.data === "reload") {
socket.close();
location.reload();
}
};
window.onbeforeunload = function() {
socket.close();
}
</script>
<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>

3290
book/Expansion.html Normal file

File diff suppressed because it is too large Load Diff

335
book/Files.html Normal file
View File

@ -0,0 +1,335 @@
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Files - Zsh Manual</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 -->
</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 "><a href="The-Z-Shell-Manual.html"><strong aria-hidden="true">1.</strong> The Z Shell Manual</a></li><li class="chapter-item expanded "><a href="Introduction.html"><strong aria-hidden="true">2.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="Roadmap.html"><strong aria-hidden="true">3.</strong> Roadmap</a></li><li class="chapter-item expanded "><a href="Invocation.html"><strong aria-hidden="true">4.</strong> Invocation</a></li><li class="chapter-item expanded "><a href="Files.html" class="active"><strong aria-hidden="true">5.</strong> Files</a></li><li class="chapter-item expanded "><a href="Shell-Grammar.html"><strong aria-hidden="true">6.</strong> Shell Grammar</a></li><li class="chapter-item expanded "><a href="Redirection.html"><strong aria-hidden="true">7.</strong> Redirection</a></li><li class="chapter-item expanded "><a href="Command-Execution.html"><strong aria-hidden="true">8.</strong> Command Execution</a></li><li class="chapter-item expanded "><a href="Functions.html"><strong aria-hidden="true">9.</strong> Functions</a></li><li class="chapter-item expanded "><a href="Jobs-_0026-Signals.html"><strong aria-hidden="true">10.</strong> Jobs &amp; Signals</a></li><li class="chapter-item expanded "><a href="Arithmetic-Evaluation.html"><strong aria-hidden="true">11.</strong> Arithmetic Evaluation</a></li><li class="chapter-item expanded "><a href="Conditional-Expressions.html"><strong aria-hidden="true">12.</strong> Conditional Expressions</a></li><li class="chapter-item expanded "><a href="Prompt-Expansion.html"><strong aria-hidden="true">13.</strong> Prompt Expansion</a></li><li class="chapter-item expanded "><a href="Expansion.html"><strong aria-hidden="true">14.</strong> Expansion</a></li><li class="chapter-item expanded "><a href="Parameters.html"><strong aria-hidden="true">15.</strong> Parameters</a></li><li class="chapter-item expanded "><a href="Options.html"><strong aria-hidden="true">16.</strong> Options</a></li><li class="chapter-item expanded "><a href="Shell-Builtin-Commands.html"><strong aria-hidden="true">17.</strong> Shell Builtin Commands</a></li><li class="chapter-item expanded "><a href="Zsh-Line-Editor.html"><strong aria-hidden="true">18.</strong> Zsh Line Editor</a></li><li class="chapter-item expanded "><a href="Completion-Widgets.html"><strong aria-hidden="true">19.</strong> Completion Widgets</a></li><li class="chapter-item expanded "><a href="Completion-System.html"><strong aria-hidden="true">20.</strong> Completion System</a></li><li class="chapter-item expanded "><a href="Completion-Using-compctl.html"><strong aria-hidden="true">21.</strong> Completion Using compctl</a></li><li class="chapter-item expanded "><a href="Zsh-Modules.html"><strong aria-hidden="true">22.</strong> Zsh Modules</a></li><li class="chapter-item expanded "><a href="Calendar-Function-System.html"><strong aria-hidden="true">23.</strong> Calendar Function System</a></li><li class="chapter-item expanded "><a href="TCP-Function-System.html"><strong aria-hidden="true">24.</strong> TCP Function System</a></li><li class="chapter-item expanded "><a href="Zftp-Function-System.html"><strong aria-hidden="true">25.</strong> Zftp Function System</a></li><li class="chapter-item expanded "><a href="User-Contributions.html"><strong aria-hidden="true">26.</strong> User Contributions</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>
</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 Manual</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" name="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="#5-files">5 Files</a>
<ul>
<li><a href="#51-startupshutdown-files">5.1 Startup/Shutdown Files</a></li>
<li><a href="#52-files">5.2 Files</a></li>
</ul>
</li>
</ul>
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<p><span id="Files"></span> <span id="Files-1"></span></p>
<h1 id="5-files"><a class="header" href="#5-files">5 Files</a></h1>
<hr />
<p><span id="Startup_002fShutdown-Files"></span></p>
<h2 id="51-startupshutdown-files"><a class="header" href="#51-startupshutdown-files">5.1 Startup/Shutdown Files</a></h2>
<p><span id="index-files_002c-startup"></span>
<span id="index-startup-files"></span>
<span id="index-files_002c-shutdown"></span>
<span id="index-shutdown-files"></span>
<span id="index-RCS_002c-use-of"></span>
<span id="index-GLOBAL_005fRCS_002c-use-of"></span>
<span id="index-NO_005fRCS_002c-use-of"></span>
<span id="index-NO_005fGLOBAL_005fRCS_002c-use-of"></span>
<span id="index-ZDOTDIR_002c-use-of"></span>
<span id="index-zshenv"></span></p>
<p>Commands are first read from <code>/etc/zshenv</code>; this cannot be overridden.
Subsequent behaviour is modified by the <code>RCS</code> and <code>GLOBAL_RCS</code> options;
the former affects all startup files, while the second only affects
global startup files (those shown here with an path starting with a
<code>/</code>). If one of the options is unset at any point, any subsequent
startup file(s) of the corresponding type will not be read. It is also
possible for a file in <code>$ZDOTDIR</code> to re-enable <code>GLOBAL_RCS</code>. Both <code>RCS</code>
and <code>GLOBAL_RCS</code> are set by default.</p>
<p>Commands are then read from <code>$ZDOTDIR/.zshenv</code>.
<span id="index-LOGIN_002c-use-of"></span>
<span id="index-zprofile"></span> If the shell is a login shell,
commands are read from <code>/etc/zprofile</code> and then <code>$ZDOTDIR/.zprofile</code>.
<span id="index-zshrc"></span> Then, if the shell is interactive,
commands are read from <code>/etc/zshrc</code> and then <code>$ZDOTDIR/.zshrc</code>.
<span id="index-zlogin"></span> Finally, if the shell is a login shell,
<code>/etc/zlogin</code> and <code>$ZDOTDIR/.zlogin</code> are read.</p>
<p><span id="index-zlogout"></span></p>
<p>When a login shell exits, the files <code>$ZDOTDIR/.zlogout</code> and then
<code>/etc/zlogout</code> are read. This happens with either an explicit exit via
the <code>exit</code> or <code>logout</code> commands, or an implicit exit by reading
end-of-file from the terminal. However, if the shell terminates due to
<code>exec</code>ing another process, the logout files are not read. These are
also affected by the <code>RCS</code> and <code>GLOBAL_RCS</code> options. Note also that the
<code>RCS</code> option affects the saving of history files, i.e. if <code>RCS</code> is unset
when the shell exits, no history file will be saved.</p>
<p><span id="index-HOME_002c-use-of"></span></p>
<p>If <code>ZDOTDIR</code> is unset, <code>HOME</code> is used instead. Files listed above as
being in <code>/etc</code> may be in another directory, depending on the
installation.</p>
<p>As <code>/etc/zshenv</code> is run for all instances of zsh, it is important that
it be kept as small as possible. In particular, it is a good idea to put
code that does not need to be run for every single shell behind a test
of the form <code>if [[ -o rcs ]]; then ...</code> so that it will not be
executed when zsh is invoked with the <code>-f</code> option.</p>
<hr />
<p><span id="Files-2"></span></p>
<h2 id="52-files"><a class="header" href="#52-files">5.2 Files</a></h2>
<p><span id="index-files-used"></span></p>
<p><code>$ZDOTDIR/.zshenv</code></p>
<p><code>$ZDOTDIR/.zprofile</code></p>
<p><code>$ZDOTDIR/.zshrc</code></p>
<p><code>$ZDOTDIR/.zlogin</code></p>
<p><code>$ZDOTDIR/.zlogout</code></p>
<p><code>${TMPPREFIX}*</code> (default is /tmp/zsh*)</p>
<p><code>/etc/zshenv</code></p>
<p><code>/etc/zprofile</code></p>
<p><code>/etc/zshrc</code></p>
<p><code>/etc/zlogin</code></p>
<p><code>/etc/zlogout</code> (installation-specific - <code>/etc</code> is the default)</p>
<p>Any of these files may be pre-compiled with the <code>zcompile</code> builtin
command (<a href="Shell-Builtin-Commands.html#Shell-Builtin-Commands">Shell Builtin
Commands</a>). If a
compiled file exists (named for the original file plus the <code>.zwc</code>
extension) and it is newer than the original file, the compiled file
will be used instead.</p>
<hr />
<p>This document was generated on <em>February 15, 2020</em> using
<a href="http://www.nongnu.org/texi2html/"><em>texi2html 5.0</em></a>.<br />
Zsh version 5.8, released on February 14, 2020.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="Invocation.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="Shell-Grammar.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="Invocation.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="Shell-Grammar.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>
<!-- Livereload script (if served using the cli tool) -->
<script type="text/javascript">
var socket = new WebSocket("ws://localhost:3000/__livereload");
socket.onmessage = function (event) {
if (event.data === "reload") {
socket.close();
location.reload();
}
};
window.onbeforeunload = function() {
socket.close();
}
</script>
<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>

4
book/FontAwesome/css/font-awesome.css vendored Normal file

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 434 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

650
book/Functions.html Normal file
View File

@ -0,0 +1,650 @@
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Functions - Zsh Manual</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 -->
</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 "><a href="The-Z-Shell-Manual.html"><strong aria-hidden="true">1.</strong> The Z Shell Manual</a></li><li class="chapter-item expanded "><a href="Introduction.html"><strong aria-hidden="true">2.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="Roadmap.html"><strong aria-hidden="true">3.</strong> Roadmap</a></li><li class="chapter-item expanded "><a href="Invocation.html"><strong aria-hidden="true">4.</strong> Invocation</a></li><li class="chapter-item expanded "><a href="Files.html"><strong aria-hidden="true">5.</strong> Files</a></li><li class="chapter-item expanded "><a href="Shell-Grammar.html"><strong aria-hidden="true">6.</strong> Shell Grammar</a></li><li class="chapter-item expanded "><a href="Redirection.html"><strong aria-hidden="true">7.</strong> Redirection</a></li><li class="chapter-item expanded "><a href="Command-Execution.html"><strong aria-hidden="true">8.</strong> Command Execution</a></li><li class="chapter-item expanded "><a href="Functions.html" class="active"><strong aria-hidden="true">9.</strong> Functions</a></li><li class="chapter-item expanded "><a href="Jobs-_0026-Signals.html"><strong aria-hidden="true">10.</strong> Jobs &amp; Signals</a></li><li class="chapter-item expanded "><a href="Arithmetic-Evaluation.html"><strong aria-hidden="true">11.</strong> Arithmetic Evaluation</a></li><li class="chapter-item expanded "><a href="Conditional-Expressions.html"><strong aria-hidden="true">12.</strong> Conditional Expressions</a></li><li class="chapter-item expanded "><a href="Prompt-Expansion.html"><strong aria-hidden="true">13.</strong> Prompt Expansion</a></li><li class="chapter-item expanded "><a href="Expansion.html"><strong aria-hidden="true">14.</strong> Expansion</a></li><li class="chapter-item expanded "><a href="Parameters.html"><strong aria-hidden="true">15.</strong> Parameters</a></li><li class="chapter-item expanded "><a href="Options.html"><strong aria-hidden="true">16.</strong> Options</a></li><li class="chapter-item expanded "><a href="Shell-Builtin-Commands.html"><strong aria-hidden="true">17.</strong> Shell Builtin Commands</a></li><li class="chapter-item expanded "><a href="Zsh-Line-Editor.html"><strong aria-hidden="true">18.</strong> Zsh Line Editor</a></li><li class="chapter-item expanded "><a href="Completion-Widgets.html"><strong aria-hidden="true">19.</strong> Completion Widgets</a></li><li class="chapter-item expanded "><a href="Completion-System.html"><strong aria-hidden="true">20.</strong> Completion System</a></li><li class="chapter-item expanded "><a href="Completion-Using-compctl.html"><strong aria-hidden="true">21.</strong> Completion Using compctl</a></li><li class="chapter-item expanded "><a href="Zsh-Modules.html"><strong aria-hidden="true">22.</strong> Zsh Modules</a></li><li class="chapter-item expanded "><a href="Calendar-Function-System.html"><strong aria-hidden="true">23.</strong> Calendar Function System</a></li><li class="chapter-item expanded "><a href="TCP-Function-System.html"><strong aria-hidden="true">24.</strong> TCP Function System</a></li><li class="chapter-item expanded "><a href="Zftp-Function-System.html"><strong aria-hidden="true">25.</strong> Zftp Function System</a></li><li class="chapter-item expanded "><a href="User-Contributions.html"><strong aria-hidden="true">26.</strong> User Contributions</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>
</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 Manual</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" name="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="#9-functions">9 Functions</a>
<ul>
<li><a href="#91-autoloading-functions">9.1 Autoloading Functions</a></li>
<li><a href="#92-anonymous-functions">9.2 Anonymous Functions</a></li>
<li><a href="#93-special-functions">9.3 Special Functions</a>
<ul>
<li><a href="#931-hook-functions">9.3.1 Hook Functions</a></li>
<li><a href="#932-trap-functions">9.3.2 Trap Functions</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<p><span id="Functions"></span> <span id="Functions-3"></span></p>
<h1 id="9-functions"><a class="header" href="#9-functions">9 Functions</a></h1>
<p><span id="index-functions"></span>
<span id="index-function_002c-use-of"></span></p>
<p>Shell functions are defined with the <code>function</code> reserved word or the
special syntax <code>funcname</code> <code>()</code>. Shell functions are read in and stored
internally. Alias names are resolved when the function is read.
Functions are executed like commands with the arguments passed as
positional parameters. (See <a href="Command-Execution.html#Command-Execution">Command
Execution</a>.)</p>
<p>Functions execute in the same process as the caller and share all files
and present working directory with the caller. A trap on <code>EXIT</code> set
inside a function is executed after the function completes in the
environment of the caller.</p>
<p><span id="index-return_002c-use-of"></span></p>
<p>The <code>return</code> builtin is used to return from function calls.</p>
<p><span id="index-functions_002c-use-of"></span></p>
<p>Function identifiers can be listed with the <code>functions</code> builtin.
<span id="index-unfunction_002c-use-of"></span> Functions can be
undefined with the <code>unfunction</code> builtin.</p>
<hr />
<p><span id="Autoloading-Functions"></span></p>
<h2 id="91-autoloading-functions"><a class="header" href="#91-autoloading-functions">9.1 Autoloading Functions</a></h2>
<p><span id="index-autoloading-functions"></span>
<span id="index-functions_002c-autoloading"></span>
<span id="index-autoload_002c-use-of"></span>
<span id="index-fpath_002c-use-of"></span></p>
<p>A function can be marked as <em>undefined</em> using the <code>autoload</code> builtin (or
<code>functions -u</code> or <code>typeset -fu</code>). Such a function has no body. When
the function is first executed, the shell searches for its definition
using the elements of the <code>fpath</code> variable. Thus to define functions for
autoloading, a typical sequence is:</p>
<div class="example">
<pre><code class="language-example">fpath=(~/myfuncs $fpath)
autoload myfunc1 myfunc2 ...
</code></pre>
</div>
<p>The usual alias expansion during reading will be suppressed if the
<code>autoload</code> builtin or its equivalent is given the option <code>-U</code>. This is
recommended for the use of functions supplied with the zsh distribution.
<span id="index-zcompile_002c-use-of"></span> Note that for functions
precompiled with the <code>zcompile</code> builtin command the flag <code>-U</code> must be
provided when the <code>.zwc</code> file is created, as the corresponding
information is compiled into the latter.</p>
<p>For each <code>element</code> in <code>fpath</code>, the shell looks for three possible files,
the newest of which is used to load the definition for the function:</p>
<ul>
<li>
<p><code>element``.zwc</code><br />
A file created with the <code>zcompile</code> builtin command, which is
expected to contain the definitions for all functions in the
directory named <code>element</code>. The file is treated in the same manner as
a directory containing files for functions and is searched for the
definition of the function. If the definition is not found, the
search for a definition proceeds with the other two possibilities
described below.</p>
<p>If <code>element</code> already includes a <code>.zwc</code> extension (i.e. the extension
was explicitly given by the user), <code>element</code> is searched for the
definition of the function without comparing its age to that of
other files; in fact, there does not need to be any directory named
<code>element</code> without the suffix. Thus including an element such as
<code>/usr/local/funcs.zwc</code> in <code>fpath</code> will speed up the search for
functions, with the disadvantage that functions included must be
explicitly recompiled by hand before the shell notices any changes.</p>
</li>
<li>
<p><code>element``/``function``.zwc</code><br />
A file created with <code>zcompile</code>, which is expected to contain the
definition for <code>function</code>. It may include other function definitions
as well, but those are neither loaded nor executed; a file found in
this way is searched <em>only</em> for the definition of <code>function</code>.</p>
</li>
<li>
<p><code>element``/``function</code><br />
A file of zsh command text, taken to be the definition for
<code>function</code>.</p>
</li>
</ul>
<p>In summary, the order of searching is, first, in the <em>parents of</em>
directories in <code>fpath</code> for the newer of either a compiled directory or a
directory in <code>fpath</code>; second, if more than one of these contains a
definition for the function that is sought, the leftmost in the <code>fpath</code>
is chosen; and third, within a directory, the newer of either a compiled
function or an ordinary function definition is used.</p>
<p><span id="index-KSH_005fAUTOLOAD_002c-use-of"></span></p>
<p>If the <code>KSH_AUTOLOAD</code> option is set, or the file contains only a simple
definition of the function, the files contents will be executed. This
will normally define the function in question, but may also perform
initialization, which is executed in the context of the function
execution, and may therefore define local parameters. It is an error if
the function is not defined by loading the file.</p>
<p>Otherwise, the function body (with no surrounding <code>funcname``() {``...``}</code>) is taken to be the complete contents of the file. This
processing of the file results in the function being re-defined, the
function itself is not re-executed. To force the shell to perform
initialization and then call the function defined, the file should
contain initialization code (which will be executed then discarded) in
addition to a complete function definition (which will be retained for
subsequent calls to the function), and a call to the shell function,
including any arguments, at the end.</p>
<p>For example, suppose the autoload file <code>func</code> contains</p>
<div class="example">
<pre><code class="language-example">func() { print This is func; }
print func is initialized
</code></pre>
</div>
<p>then <code>func; func</code> with <code>KSH_AUTOLOAD</code> set will produce both messages
on the first call, but only the message <code>This is func</code> on the second
and subsequent calls. Without <code>KSH_AUTOLOAD</code> set, it will produce the
initialization message on the first call, and the other message on the
second and subsequent calls.</p>
<p>It is also possible to create a function that is not marked as
autoloaded, but which loads its own definition by searching <code>fpath</code>, by
using <code>autoload -X</code> within a shell function. For example, the
following are equivalent:</p>
<div class="example">
<pre><code class="language-example">myfunc() {
autoload -X
}
myfunc args...
</code></pre>
</div>
<p>and</p>
<div class="example">
<pre><code class="language-example">unfunction myfunc # if myfunc was defined
autoload myfunc
myfunc args...
</code></pre>
</div>
<p>In fact, the <code>functions</code> command outputs <code>builtin autoload -X</code> as the
body of an autoloaded function. This is done so that</p>
<div class="example">
<pre><code class="language-example">eval &quot;$(functions)&quot;
</code></pre>
</div>
<p>produces a reasonable result. A true autoloaded function can be
identified by the presence of the comment <code># undefined</code> in the body,
because all comments are discarded from defined functions.</p>
<p>To load the definition of an autoloaded function <code>myfunc</code> without
executing <code>myfunc</code>, use:</p>
<div class="example">
<pre><code class="language-example">autoload +X myfunc
</code></pre>
</div>
<hr />
<p><span id="Anonymous-Functions"></span></p>
<h2 id="92-anonymous-functions"><a class="header" href="#92-anonymous-functions">9.2 Anonymous Functions</a></h2>
<p><span id="index-anonymous-functions"></span>
<span id="index-functions_002c-anonymous"></span></p>
<p>If no name is given for a function, it is anonymous and is handled
specially. Either form of function definition may be used: a <code>()</code> with
no preceding name, or a <code>function</code> with an immediately following open
brace. The function is executed immediately at the point of definition
and is not stored for future use. The function name is set to
<code>(anon)</code>.</p>
<p>Arguments to the function may be specified as words following the
closing brace defining the function, hence if there are none no
arguments (other than <code>$0</code>) are set. This is a difference from the way
other functions are parsed: normal function definitions may be followed
by certain keywords such as <code>else</code> or <code>fi</code>, which will be treated as
arguments to anonymous functions, so that a newline or semicolon is
needed to force keyword interpretation.</p>
<p>Note also that the argument list of any enclosing script or function is
hidden (as would be the case for any other function called at this
point).</p>
<p>Redirections may be applied to the anonymous function in the same manner
as to a current-shell structure enclosed in braces. The main use of
anonymous functions is to provide a scope for local variables. This is
particularly convenient in start-up files as these do not provide their
own local variable scope.</p>
<p>For example,</p>
<div class="example">
<pre><code class="language-example">variable=outside
function {
local variable=inside
print &quot;I am $variable with arguments $*&quot;
} this and that
print &quot;I am $variable&quot;
</code></pre>
</div>
<p>outputs the following:</p>
<div class="example">
<pre><code class="language-example">I am inside with arguments this and that
I am outside
</code></pre>
</div>
<p>Note that function definitions with arguments that expand to nothing,
for example <code>name=; function $name { ``...`` }</code>, are not treated
as anonymous functions. Instead, they are treated as normal function
definitions where the definition is silently discarded.</p>
<hr />
<p><span id="Special-Functions"></span></p>
<h2 id="93-special-functions"><a class="header" href="#93-special-functions">9.3 Special Functions</a></h2>
<p>Certain functions, if defined, have special meaning to the shell.</p>
<hr />
<p><span id="Hook-Functions"></span></p>
<h3 id="931-hook-functions"><a class="header" href="#931-hook-functions">9.3.1 Hook Functions</a></h3>
<p><span id="index-functions_002c-hook"></span>
<span id="index-hook-functions"></span></p>
<p>For the functions below, it is possible to define an array that has the
same name as the function with <code>_functions</code> appended. Any element in
such an array is taken as the name of a function to execute; it is
executed in the same context and with the same arguments as the basic
function. For example, if <code>$chpwd_functions</code> is an array containing the
values <code>mychpwd</code>, <code>chpwd_save_dirstack</code>, then the shell attempts to
execute the functions <code>chpwd</code>, <code>mychpwd</code> and
<code>chpwd_save_dirstack</code>, in that order. Any function that does not
exist is silently ignored. A function found by this mechanism is
referred to elsewhere as a hook function. An error in any function
causes subsequent functions not to be run. Note further that an error in
a <code>precmd</code> hook causes an immediately following <code>periodic</code> function not
to run (though it may run at the next opportunity).</p>
<p><span id="index-chpwd"></span>
<span id="index-chpwd_005ffunctions"></span></p>
<p><code>chpwd</code></p>
<p>Executed whenever the current working directory is changed.</p>
<p><span id="index-periodic"></span>
<span id="index-periodic_005ffunctions"></span></p>
<p><code>periodic</code></p>
<p><span id="index-PERIOD"></span></p>
<p>If the parameter <code>PERIOD</code> is set, this function is executed every
<code>$PERIOD</code> seconds, just before a prompt. Note that if multiple functions
are defined using the array <code>periodic_functions</code> only one period is
applied to the complete set of functions, and the scheduled time is not
reset if the list of functions is altered. Hence the set of functions is
always called together.</p>
<p><span id="index-precmd"></span>
<span id="index-precmd_005ffunctions"></span></p>
<p><code>precmd</code></p>
<p>Executed before each prompt. Note that precommand functions are not
re-executed simply because the command line is redrawn, as happens, for
example, when a notification about an exiting job is displayed.</p>
<p><span id="index-preexec"></span>
<span id="index-preexec_005ffunctions"></span></p>
<p><code>preexec</code></p>
<p>Executed just after a command has been read and is about to be executed.
If the history mechanism is active (regardless of whether the line was
discarded from the history buffer), the string that the user typed is
passed as the first argument, otherwise it is an empty string. The
actual command that will be executed (including expanded aliases) is
passed in two different forms: the second argument is a single-line,
size-limited version of the command (with things like function bodies
elided); the third argument contains the full text that is being
executed.</p>
<p><span id="index-zshaddhistory"></span>
<span id="index-zshaddhistory_005ffunctions"></span></p>
<p><code>zshaddhistory</code></p>
<p><span id="index-history_002c-hook-when-line-is-saved"></span></p>
<p>Executed when a history line has been read interactively, but before it
is executed. The sole argument is the complete history line (so that any
terminating newline will still be present).</p>
<p>If any of the hook functions returns status 1 (or any non-zero value
other than 2, though this is not guaranteed for future versions of the
shell) the history line will not be saved, although it lingers in the
history until the next line is executed, allowing you to reuse or edit
it immediately.</p>
<p>If any of the hook functions returns status 2 the history line will be
saved on the internal history list, but not written to the history file.
In case of a conflict, the first non-zero status value is taken.</p>
<p>A hook function may call <code>fc -p</code> <code>...</code> to switch the history context
so that the history is saved in a different file from the that in the
global <code>HISTFILE</code> parameter. This is handled specially: the history
context is automatically restored after the processing of the history
line is finished.</p>
<p>The following example function works with one of the options
<code>INC_APPEND_HISTORY</code> or <code>SHARE_HISTORY</code> set, in order that the line is
written out immediately after the history entry is added. It first adds
the history line to the normal history with the newline stripped, which
is usually the correct behaviour. Then it switches the history context
so that the line will be written to a history file in the current
directory.</p>
<div class="example">
<pre><code class="language-example">zshaddhistory() {
print -sr -- ${1%%$'\n'}
fc -p .zsh_local_history
}
</code></pre>
</div>
<p><span id="index-zshexit"></span>
<span id="index-zshexit_005ffunctions"></span></p>
<p><code>zshexit</code></p>
<p>Executed at the point where the main shell is about to exit normally.
This is not called by exiting subshells, nor when the <code>exec</code> precommand
modifier is used before an external command. Also, unlike <code>TRAPEXIT</code>, it
is not called when functions exit.</p>
<hr />
<p><span id="Trap-Functions"></span></p>
<h3 id="932-trap-functions"><a class="header" href="#932-trap-functions">9.3.2 Trap Functions</a></h3>
<p>The functions below are treated specially but do not have corresponding
hook arrays.</p>
<ul>
<li>
<p><code>TRAP``NAL</code><br />
<span id="index-signals_002c-trapping"></span>
<span id="index-trapping-signals"></span></p>
<p>If defined and non-null, this function will be executed whenever the
shell catches a signal <code>SIG``NAL</code>, where <code>NAL</code> is a signal name as
specified for the <code>kill</code> builtin. The signal number will be passed
as the first parameter to the function.</p>
<p>If a function of this form is defined and null, the shell and
processes spawned by it will ignore <code>SIG``NAL</code>.</p>
<p>The return status from the function is handled specially. If it is
zero, the signal is assumed to have been handled, and execution
continues normally. Otherwise, the shell will behave as interrupted
except that the return status of the trap is retained.</p>
<p>Programs terminated by uncaught signals typically return the status
128 plus the signal number. Hence the following causes the handler
for <code>SIGINT</code> to print a message, then mimic the usual effect of the
signal.</p>
<div class="example">
<pre><code class="language-example">TRAPINT() {
print &quot;Caught SIGINT, aborting.&quot;
return $(( 128 + $1 ))
}
</code></pre>
</div>
<p>The functions <code>TRAPZERR</code>, <code>TRAPDEBUG</code> and <code>TRAPEXIT</code> are never
executed inside other traps.</p>
<p><span id="index-TRAPDEBUG"></span></p>
</li>
<li>
<p><code>TRAPDEBUG</code><br />
If the option <code>DEBUG_BEFORE_CMD</code> is set (as it is by default),
executed before each command; otherwise executed after each command.
See the description of the <code>trap</code> builtin in <a href="Shell-Builtin-Commands.html#Shell-Builtin-Commands">Shell Builtin
Commands</a> for
details of additional features provided in debug traps.</p>
<p><span id="index-TRAPEXIT"></span></p>
</li>
<li>
<p><code>TRAPEXIT</code><br />
Executed when the shell exits, or when the current function exits if
defined inside a function. The value of <code>$?</code> at the start of
execution is the exit status of the shell or the return status of
the function exiting.</p>
<p><span id="index-TRAPZERR"></span> <span id="index-TRAPERR"></span></p>
</li>
<li>
<p><code>TRAPZERR</code><br />
Executed whenever a command has a non-zero exit status. However, the
function is not executed if the command occurred in a sublist
followed by <code>&amp;&amp;</code> or <code>||</code>; only the final command in a sublist of
this type causes the trap to be executed. The function <code>TRAPERR</code>
acts the same as <code>TRAPZERR</code> on systems where there is no <code>SIGERR</code>
(this is the usual case).</p>
</li>
</ul>
<p><span id="index-trap_002c-use-of"></span></p>
<p>The functions beginning <code>TRAP</code> may alternatively be defined with the
<code>trap</code> builtin: this may be preferable for some uses. Setting a trap
with one form removes any trap of the other form for the same signal;
removing a trap in either form removes all traps for the same signal.
The forms</p>
<div class="example">
<pre><code class="language-example">TRAPNAL() {
# code
}
</code></pre>
</div>
<p>(function traps) and</p>
<div class="example">
<pre><code class="language-example">trap '
# code
' NAL
</code></pre>
</div>
<p>(list traps) are equivalent in most ways, the exceptions being the
following:</p>
<ul>
<li>Function traps have all the properties of normal functions,
appearing in the list of functions and being called with their own
function context rather than the context where the trap was
triggered.</li>
<li>The return status from function traps is special, whereas a return
from a list trap causes the surrounding context to return with the
given status.</li>
<li>Function traps are not reset within subshells, in accordance with
zsh behaviour; list traps are reset, in accordance with POSIX
behaviour.</li>
</ul>
<hr />
<p>This document was generated on <em>February 15, 2020</em> using
<a href="http://www.nongnu.org/texi2html/"><em>texi2html 5.0</em></a>.<br />
Zsh version 5.8, released on February 14, 2020.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="Command-Execution.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="Jobs-_0026-Signals.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="Command-Execution.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="Jobs-_0026-Signals.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>
<!-- Livereload script (if served using the cli tool) -->
<script type="text/javascript">
var socket = new WebSocket("ws://localhost:3000/__livereload");
socket.onmessage = function (event) {
if (event.data === "reload") {
socket.close();
location.reload();
}
};
window.onbeforeunload = function() {
socket.close();
}
</script>
<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>

377
book/Introduction.html Normal file
View File

@ -0,0 +1,377 @@
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Introduction - Zsh Manual</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 -->
</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 "><a href="The-Z-Shell-Manual.html"><strong aria-hidden="true">1.</strong> The Z Shell Manual</a></li><li class="chapter-item expanded "><a href="Introduction.html" class="active"><strong aria-hidden="true">2.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="Roadmap.html"><strong aria-hidden="true">3.</strong> Roadmap</a></li><li class="chapter-item expanded "><a href="Invocation.html"><strong aria-hidden="true">4.</strong> Invocation</a></li><li class="chapter-item expanded "><a href="Files.html"><strong aria-hidden="true">5.</strong> Files</a></li><li class="chapter-item expanded "><a href="Shell-Grammar.html"><strong aria-hidden="true">6.</strong> Shell Grammar</a></li><li class="chapter-item expanded "><a href="Redirection.html"><strong aria-hidden="true">7.</strong> Redirection</a></li><li class="chapter-item expanded "><a href="Command-Execution.html"><strong aria-hidden="true">8.</strong> Command Execution</a></li><li class="chapter-item expanded "><a href="Functions.html"><strong aria-hidden="true">9.</strong> Functions</a></li><li class="chapter-item expanded "><a href="Jobs-_0026-Signals.html"><strong aria-hidden="true">10.</strong> Jobs &amp; Signals</a></li><li class="chapter-item expanded "><a href="Arithmetic-Evaluation.html"><strong aria-hidden="true">11.</strong> Arithmetic Evaluation</a></li><li class="chapter-item expanded "><a href="Conditional-Expressions.html"><strong aria-hidden="true">12.</strong> Conditional Expressions</a></li><li class="chapter-item expanded "><a href="Prompt-Expansion.html"><strong aria-hidden="true">13.</strong> Prompt Expansion</a></li><li class="chapter-item expanded "><a href="Expansion.html"><strong aria-hidden="true">14.</strong> Expansion</a></li><li class="chapter-item expanded "><a href="Parameters.html"><strong aria-hidden="true">15.</strong> Parameters</a></li><li class="chapter-item expanded "><a href="Options.html"><strong aria-hidden="true">16.</strong> Options</a></li><li class="chapter-item expanded "><a href="Shell-Builtin-Commands.html"><strong aria-hidden="true">17.</strong> Shell Builtin Commands</a></li><li class="chapter-item expanded "><a href="Zsh-Line-Editor.html"><strong aria-hidden="true">18.</strong> Zsh Line Editor</a></li><li class="chapter-item expanded "><a href="Completion-Widgets.html"><strong aria-hidden="true">19.</strong> Completion Widgets</a></li><li class="chapter-item expanded "><a href="Completion-System.html"><strong aria-hidden="true">20.</strong> Completion System</a></li><li class="chapter-item expanded "><a href="Completion-Using-compctl.html"><strong aria-hidden="true">21.</strong> Completion Using compctl</a></li><li class="chapter-item expanded "><a href="Zsh-Modules.html"><strong aria-hidden="true">22.</strong> Zsh Modules</a></li><li class="chapter-item expanded "><a href="Calendar-Function-System.html"><strong aria-hidden="true">23.</strong> Calendar Function System</a></li><li class="chapter-item expanded "><a href="TCP-Function-System.html"><strong aria-hidden="true">24.</strong> TCP Function System</a></li><li class="chapter-item expanded "><a href="Zftp-Function-System.html"><strong aria-hidden="true">25.</strong> Zftp Function System</a></li><li class="chapter-item expanded "><a href="User-Contributions.html"><strong aria-hidden="true">26.</strong> User Contributions</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>
</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 Manual</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" name="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="#2-introduction">2 Introduction</a>
<ul>
<li><a href="#21-author">2.1 Author</a></li>
<li><a href="#22-availability">2.2 Availability</a></li>
<li><a href="#23-mailing-lists">2.3 Mailing Lists</a></li>
<li><a href="#24-the-zsh-faq">2.4 The Zsh FAQ</a></li>
<li><a href="#25-the-zsh-web-page">2.5 The Zsh Web Page</a></li>
<li><a href="#26-the-zsh-userguide">2.6 The Zsh Userguide</a></li>
<li><a href="#27-see-also">2.7 See Also</a></li>
</ul>
</li>
</ul>
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<p><span id="Introduction"></span> <span id="Introduction-1"></span></p>
<h1 id="2-introduction"><a class="header" href="#2-introduction">2 Introduction</a></h1>
<p><span id="index-introduction"></span></p>
<p>Zsh is a UNIX command interpreter (shell) usable as an interactive login
shell and as a shell script command processor. Of the standard shells,
zsh most closely resembles ksh but includes many enhancements. It does
not provide compatibility with POSIX or other shells in its default
operating mode: see the section
<a href="Invocation.html#Compatibility">Compatibility</a>.</p>
<p>Zsh has command line editing, builtin spelling correction, programmable
command completion, shell functions (with autoloading), a history
mechanism, and a host of other features.</p>
<hr />
<p><span id="Author"></span> <span id="Author-1"></span></p>
<h2 id="21-author"><a class="header" href="#21-author">2.1 Author</a></h2>
<p><span id="index-author"></span></p>
<p>Zsh was originally written by Paul Falstad <code>&lt;pf@zsh.org&gt;</code>. Zsh is now
maintained by the members of the zsh-workers mailing list
<code>&lt;zsh-workers@zsh.org&gt;</code>. The development is currently coordinated by
Peter Stephenson <code>&lt;pws@zsh.org&gt;</code>. The coordinator can be contacted at
<code>&lt;coordinator@zsh.org&gt;</code>, but matters relating to the code should
generally go to the mailing list.</p>
<hr />
<p><span id="Availability"></span> <span id="Availability-1"></span></p>
<h2 id="22-availability"><a class="header" href="#22-availability">2.2 Availability</a></h2>
<p>Zsh is available from the following HTTP and anonymous FTP site.</p>
<p><span id="index-FTP-sites-for-zsh"></span>
<span id="index-acquiring-zsh-by-FTP"></span>
<span id="index-availability-of-zsh"></span></p>
<p><code>ftp://ftp.zsh.org/pub/</code><br />
<code>https://www.zsh.org/pub/</code> )</p>
<p>The up-to-date source code is available via Git from Sourceforge. See
<code>https://sourceforge.net/projects/zsh/</code> for details. A summary of
instructions for the archive can be found at
<code>http://zsh.sourceforge.net/</code>.</p>
<hr />
<p><span id="Mailing-Lists"></span> <span id="Mailing-Lists-1"></span></p>
<h2 id="23-mailing-lists"><a class="header" href="#23-mailing-lists">2.3 Mailing Lists</a></h2>
<p><span id="index-mailing-lists"></span></p>
<p>Zsh has 3 mailing lists:</p>
<ul>
<li>
<p><code>&lt;zsh-announce@zsh.org&gt;</code><br />
Announcements about releases, major changes in the shell and the
monthly posting of the Zsh FAQ. (moderated)</p>
</li>
<li>
<p><code>&lt;zsh-users@zsh.org&gt;</code><br />
User discussions.</p>
</li>
<li>
<p><code>&lt;zsh-workers@zsh.org&gt;</code><br />
Hacking, development, bug reports and patches.</p>
</li>
</ul>
<p>To subscribe or unsubscribe, send mail to the associated administrative
address for the mailing list.</p>
<p><code>&lt;zsh-announce-subscribe@zsh.org&gt;</code></p>
<p><code>&lt;zsh-users-subscribe@zsh.org&gt;</code></p>
<p><code>&lt;zsh-workers-subscribe@zsh.org&gt;</code></p>
<p><code>&lt;zsh-announce-unsubscribe@zsh.org&gt;</code></p>
<p><code>&lt;zsh-users-unsubscribe@zsh.org&gt;</code></p>
<p><code>&lt;zsh-workers-unsubscribe@zsh.org&gt;</code></p>
<p>YOU ONLY NEED TO JOIN ONE OF THE MAILING LISTS AS THEY ARE NESTED. All
submissions to zsh-announce are automatically forwarded to zsh-users.
All submissions to zsh-users are automatically forwarded to zsh-workers.</p>
<p>If you have problems subscribing/unsubscribing to any of the mailing
lists, send mail to <code>&lt;listmaster@zsh.org&gt;</code>. The mailing lists are
maintained by Karsten Thygesen <code>&lt;karthy@kom.auc.dk&gt;</code>.</p>
<p>The mailing lists are archived; the archives can be accessed via the
administrative addresses listed above. There is also a hypertext
archive, maintained by Geoff Wing <code>&lt;gcw@zsh.org&gt;</code>, available at
<code>https://www.zsh.org/mla/</code>.</p>
<hr />
<p><span id="The-Zsh-FAQ"></span> <span id="The-Zsh-FAQ-1"></span></p>
<h2 id="24-the-zsh-faq"><a class="header" href="#24-the-zsh-faq">2.4 The Zsh FAQ</a></h2>
<p>Zsh has a list of Frequently Asked Questions (FAQ), maintained by Peter
Stephenson <code>&lt;pws@zsh.org&gt;</code>. It is regularly posted to the newsgroup
comp.unix.shell and the zsh-announce mailing list. The latest version
can be found at any of the Zsh FTP sites, or at
<code>http://www.zsh.org/FAQ/</code>. The contact address for FAQ-related matters
is <code>&lt;faqmaster@zsh.org&gt;</code>.</p>
<hr />
<p><span id="The-Zsh-Web-Page"></span>
<span id="The-Zsh-Web-Page-1"></span></p>
<h2 id="25-the-zsh-web-page"><a class="header" href="#25-the-zsh-web-page">2.5 The Zsh Web Page</a></h2>
<p>Zsh has a web page which is located at <code>https://www.zsh.org/</code>. This is
maintained by Karsten Thygesen <code>&lt;karthy@zsh.org&gt;</code>, of SunSITE Denmark.
The contact address for web-related matters is <code>&lt;webmaster@zsh.org&gt;</code>.</p>
<hr />
<p><span id="The-Zsh-Userguide"></span>
<span id="The-Zsh-Userguide-1"></span></p>
<h2 id="26-the-zsh-userguide"><a class="header" href="#26-the-zsh-userguide">2.6 The Zsh Userguide</a></h2>
<p>A userguide is currently in preparation. It is intended to complement
the manual, with explanations and hints on issues where the manual can
be cabbalistic, hierographic, or downright mystifying (for example, the
word hierographic does not exist). It can be viewed in its current
state at <code>http://zsh.sourceforge.net/Guide/</code>. At the time of writing,
chapters dealing with startup files and their contents and the new
completion system were essentially complete.</p>
<hr />
<p><span id="See-Also"></span> <span id="See-Also-1"></span></p>
<h2 id="27-see-also"><a class="header" href="#27-see-also">2.7 See Also</a></h2>
<p>man page sh(1), man page csh(1), man page tcsh(1), man page rc(1), man
page bash(1), man page ksh(1)</p>
<p>IEEE Standard for information Technology - Part 2: Shell and Utilities,
IEEE Inc, 1993, ISBN 1-55937-255-9.</p>
<hr />
<p>This document was generated on <em>February 15, 2020</em> using
<a href="http://www.nongnu.org/texi2html/"><em>texi2html 5.0</em></a>.<br />
Zsh version 5.8, released on February 14, 2020.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="The-Z-Shell-Manual.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="Roadmap.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="The-Z-Shell-Manual.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="Roadmap.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>
<!-- Livereload script (if served using the cli tool) -->
<script type="text/javascript">
var socket = new WebSocket("ws://localhost:3000/__livereload");
socket.onmessage = function (event) {
if (event.data === "reload") {
socket.close();
location.reload();
}
};
window.onbeforeunload = function() {
socket.close();
}
</script>
<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>

470
book/Invocation.html Normal file
View File

@ -0,0 +1,470 @@
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Invocation - Zsh Manual</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 -->
</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 "><a href="The-Z-Shell-Manual.html"><strong aria-hidden="true">1.</strong> The Z Shell Manual</a></li><li class="chapter-item expanded "><a href="Introduction.html"><strong aria-hidden="true">2.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="Roadmap.html"><strong aria-hidden="true">3.</strong> Roadmap</a></li><li class="chapter-item expanded "><a href="Invocation.html" class="active"><strong aria-hidden="true">4.</strong> Invocation</a></li><li class="chapter-item expanded "><a href="Files.html"><strong aria-hidden="true">5.</strong> Files</a></li><li class="chapter-item expanded "><a href="Shell-Grammar.html"><strong aria-hidden="true">6.</strong> Shell Grammar</a></li><li class="chapter-item expanded "><a href="Redirection.html"><strong aria-hidden="true">7.</strong> Redirection</a></li><li class="chapter-item expanded "><a href="Command-Execution.html"><strong aria-hidden="true">8.</strong> Command Execution</a></li><li class="chapter-item expanded "><a href="Functions.html"><strong aria-hidden="true">9.</strong> Functions</a></li><li class="chapter-item expanded "><a href="Jobs-_0026-Signals.html"><strong aria-hidden="true">10.</strong> Jobs &amp; Signals</a></li><li class="chapter-item expanded "><a href="Arithmetic-Evaluation.html"><strong aria-hidden="true">11.</strong> Arithmetic Evaluation</a></li><li class="chapter-item expanded "><a href="Conditional-Expressions.html"><strong aria-hidden="true">12.</strong> Conditional Expressions</a></li><li class="chapter-item expanded "><a href="Prompt-Expansion.html"><strong aria-hidden="true">13.</strong> Prompt Expansion</a></li><li class="chapter-item expanded "><a href="Expansion.html"><strong aria-hidden="true">14.</strong> Expansion</a></li><li class="chapter-item expanded "><a href="Parameters.html"><strong aria-hidden="true">15.</strong> Parameters</a></li><li class="chapter-item expanded "><a href="Options.html"><strong aria-hidden="true">16.</strong> Options</a></li><li class="chapter-item expanded "><a href="Shell-Builtin-Commands.html"><strong aria-hidden="true">17.</strong> Shell Builtin Commands</a></li><li class="chapter-item expanded "><a href="Zsh-Line-Editor.html"><strong aria-hidden="true">18.</strong> Zsh Line Editor</a></li><li class="chapter-item expanded "><a href="Completion-Widgets.html"><strong aria-hidden="true">19.</strong> Completion Widgets</a></li><li class="chapter-item expanded "><a href="Completion-System.html"><strong aria-hidden="true">20.</strong> Completion System</a></li><li class="chapter-item expanded "><a href="Completion-Using-compctl.html"><strong aria-hidden="true">21.</strong> Completion Using compctl</a></li><li class="chapter-item expanded "><a href="Zsh-Modules.html"><strong aria-hidden="true">22.</strong> Zsh Modules</a></li><li class="chapter-item expanded "><a href="Calendar-Function-System.html"><strong aria-hidden="true">23.</strong> Calendar Function System</a></li><li class="chapter-item expanded "><a href="TCP-Function-System.html"><strong aria-hidden="true">24.</strong> TCP Function System</a></li><li class="chapter-item expanded "><a href="Zftp-Function-System.html"><strong aria-hidden="true">25.</strong> Zftp Function System</a></li><li class="chapter-item expanded "><a href="User-Contributions.html"><strong aria-hidden="true">26.</strong> User Contributions</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>
</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 Manual</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" name="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="#4-invocation">4 Invocation</a>
<ul>
<li><a href="#41-invocation">4.1 Invocation</a></li>
<li><a href="#42-compatibility">4.2 Compatibility</a></li>
<li><a href="#43-restricted-shell">4.3 Restricted Shell</a></li>
</ul>
</li>
</ul>
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<p><span id="Invocation"></span> <span id="Invocation-1"></span></p>
<h1 id="4-invocation"><a class="header" href="#4-invocation">4 Invocation</a></h1>
<p><span id="index-invocation"></span></p>
<hr />
<p><span id="Invocation-2"></span></p>
<h2 id="41-invocation"><a class="header" href="#41-invocation">4.1 Invocation</a></h2>
<p><span id="index-shell-options"></span>
<span id="index-options_002c-shell"></span>
<span id="index-shell-flags"></span>
<span id="index-flags_002c-shell"></span></p>
<p>The following flags are interpreted by the shell when invoked to
determine where the shell will read commands from:</p>
<ul>
<li>
<p><code>-c</code><br />
Take the first argument as a command to execute, rather than reading
commands from a script or standard input. If any further arguments
are given, the first one is assigned to <code>$0</code>, rather than being used
as a positional parameter.</p>
</li>
<li>
<p><code>-i</code><br />
Force shell to be interactive. It is still possible to specify a
script to execute.</p>
</li>
<li>
<p><code>-s</code><br />
Force shell to read commands from the standard input. If the <code>-s</code>
flag is not present and an argument is given, the first argument is
taken to be the pathname of a script to execute.</p>
</li>
</ul>
<p>If there are any remaining arguments after option processing, and
neither of the options <code>-c</code> or <code>-s</code> was supplied, the first argument is
taken as the file name of a script containing shell commands to be
executed. If the option <code>PATH_SCRIPT</code> is set, and the file name does not
contain a directory path (i.e. there is no <code>/</code> in the name), first the
current directory and then the command path given by the variable <code>PATH</code>
are searched for the script. If the option is not set or the file name
contains a <code>/</code> it is used directly.</p>
<p>After the first one or two arguments have been appropriated as described
above, the remaining arguments are assigned to the positional
parameters.</p>
<p>For further options, which are common to invocation and the <code>set</code>
builtin, see <a href="Options.html#Options">Options</a>.</p>
<p>The long option <code>-``-emulate</code> followed (in a separate word) by an
emulation mode may be passed to the shell. The emulation modes are those
described for the <code>emulate</code> builtin, see <a href="Shell-Builtin-Commands.html#Shell-Builtin-Commands">Shell Builtin
Commands</a>. The
<code>-``-emulate</code> option must precede any other options (which might
otherwise be overridden), but following options are honoured, so may be
used to modify the requested emulation mode. Note that certain extra
steps are taken to ensure a smooth emulation when this option is used
compared with the <code>emulate</code> command within the shell: for example,
variables that conflict with POSIX usage such as <code>path</code> are not defined
within the shell.</p>
<p>Options may be specified by name using the <code>-o</code> option. <code>-o</code> acts like a
single-letter option, but takes a following string as the option name.
For example,</p>
<div class="example">
<pre><code class="language-example">zsh -x -o shwordsplit scr
</code></pre>
</div>
<p>runs the script <code>scr</code>, setting the <code>XTRACE</code> option by the corresponding
letter <code>-x</code> and the <code>SH_WORD_SPLIT</code> option by name. Options may be
turned <em>off</em> by name by using <code>+o</code> instead of <code>-o</code>. <code>-o</code> can be stacked
up with preceding single-letter options, so for example <code>-xo shwordsplit</code> or <code>-xoshwordsplit</code> is equivalent to <code>-x -o shwordsplit</code>.</p>
<p><span id="index-long-option"></span></p>
<p>Options may also be specified by name in GNU long option style,
<code>-``-``option-name</code>. When this is done, <code>-</code> characters in the
option name are permitted: they are translated into <code>_</code>, and thus
ignored. So, for example, <code>zsh -``-sh-word-split</code> invokes zsh with the
<code>SH_WORD_SPLIT</code> option turned on. Like other option syntaxes, options
can be turned off by replacing the initial <code>-</code> with a <code>+</code>; thus
<code>+-sh-word-split</code> is equivalent to <code>-``-no-sh-word-split</code>. Unlike
other option syntaxes, GNU-style long options cannot be stacked with any
other options, so for example <code>-x-shwordsplit</code> is an error, rather
than being treated like <code>-x -``-shwordsplit</code>.</p>
<p><span id="index-_002d_002dversion"></span>
<span id="index-_002d_002dhelp"></span></p>
<p>The special GNU-style option <code>-``-version</code> is handled; it sends to
standard output the shells version information, then exits
successfully. <code>-``-help</code> is also handled; it sends to standard output
a list of options that can be used when invoking the shell, then exits
successfully.</p>
<p>Option processing may be finished, allowing following arguments that
start with <code>-</code> or <code>+</code> to be treated as normal arguments, in two
ways. Firstly, a lone <code>-</code> (or <code>+</code>) as an argument by itself ends
option processing. Secondly, a special option <code>-``-</code> (or <code>+-</code>),
which may be specified on its own (which is the standard POSIX usage) or
may be stacked with preceding options (so <code>-x-</code> is equivalent to <code>-x -``-</code>). Options are not permitted to be stacked after <code>-``-</code> (so
<code>-x-f</code> is an error), but note the GNU-style option form discussed
above, where <code>-``-shwordsplit</code> is permitted and does not end option
processing.</p>
<p>Except when the sh/ksh emulation single-letter options are in effect,
the option <code>-b</code> (or <code>+b</code>) ends option processing. <code>-b</code> is like
<code>-``-</code>, except that further single-letter options can be stacked
after the <code>-b</code> and will take effect as normal.</p>
<hr />
<p><span id="Compatibility"></span> <span id="Compatibility-1"></span></p>
<h2 id="42-compatibility"><a class="header" href="#42-compatibility">4.2 Compatibility</a></h2>
<p><span id="index-compatibility"></span>
<span id="index-sh-compatibility"></span>
<span id="index-ksh-compatibility"></span></p>
<p>Zsh tries to emulate sh or ksh when it is invoked as <code>sh</code> or <code>ksh</code>
respectively; more precisely, it looks at the first letter of the name
by which it was invoked, excluding any initial <code>r</code> (assumed to stand
for restricted), and if that is <code>b</code>, <code>s</code> or <code>k</code> it will emulate
sh or ksh. Furthermore, if invoked as <code>su</code> (which happens on certain
systems when the shell is executed by the <code>su</code> command), the shell will
try to find an alternative name from the <code>SHELL</code> environment variable
and perform emulation based on that.</p>
<p>In sh and ksh compatibility modes the following parameters are not
special and not initialized by the shell: <code>ARGC</code>, <code>argv</code>, <code>cdpath</code>,
<code>fignore</code>, <code>fpath</code>, <code>HISTCHARS</code>, <code>mailpath</code>, <code>MANPATH</code>, <code>manpath</code>,
<code>path</code>, <code>prompt</code>, <code>PROMPT</code>, <code>PROMPT2</code>, <code>PROMPT3</code>, <code>PROMPT4</code>, <code>psvar</code>,
<code>status</code>, <code>watch</code>.</p>
<p><span id="index-ENV_002c-use-of"></span></p>
<p>The usual zsh startup/shutdown scripts are not executed. Login shells
source <code>/etc/profile</code> followed by <code>$HOME/.profile</code>. If the <code>ENV</code>
environment variable is set on invocation, <code>$ENV</code> is sourced after the
profile scripts. The value of <code>ENV</code> is subjected to parameter expansion,
command substitution, and arithmetic expansion before being interpreted
as a pathname. Note that the <code>PRIVILEGED</code> option also affects the
execution of startup files.</p>
<p>The following options are set if the shell is invoked as <code>sh</code> or <code>ksh</code>:
<code>NO_BAD_PATTERN</code>, <code>NO_BANG_HIST</code>, <code>NO_BG_NICE</code>, <code>NO_EQUALS</code>,
<code>NO_FUNCTION_ARGZERO</code>, <code>GLOB_SUBST</code>, <code>NO_GLOBAL_EXPORT</code>, <code>NO_HUP</code>,
<code>INTERACTIVE_COMMENTS</code>, <code>KSH_ARRAYS</code>, <code>NO_MULTIOS</code>, <code>NO_NOMATCH</code>,
<code>NO_NOTIFY</code>, <code>POSIX_BUILTINS</code>, <code>NO_PROMPT_PERCENT</code>, <code>RM_STAR_SILENT</code>,
<code>SH_FILE_EXPANSION</code>, <code>SH_GLOB</code>, <code>SH_OPTION_LETTERS</code>, <code>SH_WORD_SPLIT</code>.
Additionally the <code>BSD_ECHO</code> and <code>IGNORE_BRACES</code> options are set if zsh
is invoked as <code>sh</code>. Also, the <code>KSH_OPTION_PRINT</code>, <code>LOCAL_OPTIONS</code>,
<code>PROMPT_BANG</code>, <code>PROMPT_SUBST</code> and <code>SINGLE_LINE_ZLE</code> options are set if
zsh is invoked as <code>ksh</code>.</p>
<hr />
<p><span id="Restricted-Shell"></span>
<span id="Restricted-Shell-1"></span></p>
<h2 id="43-restricted-shell"><a class="header" href="#43-restricted-shell">4.3 Restricted Shell</a></h2>
<p><span id="index-restricted-shell"></span>
<span id="index-RESTRICTED"></span></p>
<p>When the basename of the command used to invoke zsh starts with the
letter <code>r</code> or the <code>-r</code> command line option is supplied at
invocation, the shell becomes restricted. Emulation mode is determined
after stripping the letter <code>r</code> from the invocation name. The following
are disabled in restricted mode:</p>
<ul>
<li>changing directories with the <code>cd</code> builtin</li>
<li>changing or unsetting the <code>EGID</code>, <code>EUID</code>, <code>GID</code>, <code>HISTFILE</code>,
<code>HISTSIZE</code>, <code>IFS</code>, <code>LD_AOUT_LIBRARY_PATH</code>, <code>LD_AOUT_PRELOAD</code>,
<code>LD_LIBRARY_PATH</code>, <code>LD_PRELOAD</code>, <code>MODULE_PATH</code>, <code>module_path</code>,
<code>PATH</code>, <code>path</code>, <code>SHELL</code>, <code>UID</code> and <code>USERNAME</code> parameters</li>
<li>specifying command names containing <code>/</code></li>
<li>specifying command pathnames using <code>hash</code></li>
<li>redirecting output to files</li>
<li>using the <code>exec</code> builtin command to replace the shell with another
command</li>
<li>using <code>jobs -Z</code> to overwrite the shell process argument and
environment space</li>
<li>using the <code>ARGV0</code> parameter to override <code>argv[0]</code> for external
commands</li>
<li>turning off restricted mode with <code>set +r</code> or <code>unsetopt RESTRICTED</code></li>
</ul>
<p>These restrictions are enforced after processing the startup files. The
startup files should set up <code>PATH</code> to point to a directory of commands
which can be safely invoked in the restricted environment. They may also
add further restrictions by disabling selected builtins.</p>
<p>Restricted mode can also be activated any time by setting the
<code>RESTRICTED</code> option. This immediately enables all the restrictions
described above even if the shell still has not processed all startup
files.</p>
<p>A shell <em>Restricted Mode</em> is an outdated way to restrict what users may
do: modern systems have better, safer and more reliable ways to confine
user actions, such as <em>chroot jails</em>, <em>containers</em> and <em>zones</em>.</p>
<p>A restricted shell is very difficult to implement safely. The feature
may be removed in a future version of zsh.</p>
<p>It is important to realise that the restrictions only apply to the
shell, not to the commands it runs (except for some shell builtins).
While a restricted shell can only run the restricted list of commands
accessible via the predefined <code>PATH</code> variable, it does not prevent
those commands from running any other command.</p>
<p>As an example, if <code>env</code> is among the list of <em>allowed</em> commands, then
it allows the user to run any command as <code>env</code> is not a shell</p>
<p>So when implementing a restricted shell framework it is important to be
fully aware of what actions each of the <em>allowed</em> commands or features
(which may be regarded as <em>modules</em>) can perform.</p>
<p>Many commands can have their behaviour affected by environment
variables. Except for the few listed above, zsh does not restrict the
setting of environment variables.</p>
<p>If a <code>perl</code>, <code>python</code>, <code>bash</code>, or other general purpose
interpreted script it treated as a restricted command, the user can work
around the restriction by setting specially crafted <code>PERL5LIB</code>,
<code>PYTHONPATH</code>, <code>BASHENV</code> (etc.) environment variables. On GNU
systems, any command can be made to run arbitrary code when performing
character set conversion (including zsh itself) by setting a
<code>GCONV_PATH</code> environment variable. Those are only a few examples.</p>
<p>Bear in mind that, contrary to some other shells, <code>readonly</code> is not a
security feature in zsh as it can be undone and so cannot be used to
mitigate the above.</p>
<p>A restricted shell only works if the allowed commands are few and
carefully written so as not to grant more access to users than intended.
It is also important to restrict what zsh module the user may load as
some of them, such as <code>zsh/system</code>, <code>zsh/mapfile</code> and <code>zsh/files</code>,
allow bypassing most of the restrictions.</p>
<hr />
<p>This document was generated on <em>February 15, 2020</em> using
<a href="http://www.nongnu.org/texi2html/"><em>texi2html 5.0</em></a>.<br />
Zsh version 5.8, released on February 14, 2020.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="Roadmap.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="Files.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="Roadmap.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="Files.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>
<!-- Livereload script (if served using the cli tool) -->
<script type="text/javascript">
var socket = new WebSocket("ws://localhost:3000/__livereload");
socket.onmessage = function (event) {
if (event.data === "reload") {
socket.close();
location.reload();
}
};
window.onbeforeunload = function() {
socket.close();
}
</script>
<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>

View File

@ -0,0 +1,396 @@
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Jobs &amp; Signals - Zsh Manual</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 -->
</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 "><a href="The-Z-Shell-Manual.html"><strong aria-hidden="true">1.</strong> The Z Shell Manual</a></li><li class="chapter-item expanded "><a href="Introduction.html"><strong aria-hidden="true">2.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="Roadmap.html"><strong aria-hidden="true">3.</strong> Roadmap</a></li><li class="chapter-item expanded "><a href="Invocation.html"><strong aria-hidden="true">4.</strong> Invocation</a></li><li class="chapter-item expanded "><a href="Files.html"><strong aria-hidden="true">5.</strong> Files</a></li><li class="chapter-item expanded "><a href="Shell-Grammar.html"><strong aria-hidden="true">6.</strong> Shell Grammar</a></li><li class="chapter-item expanded "><a href="Redirection.html"><strong aria-hidden="true">7.</strong> Redirection</a></li><li class="chapter-item expanded "><a href="Command-Execution.html"><strong aria-hidden="true">8.</strong> Command Execution</a></li><li class="chapter-item expanded "><a href="Functions.html"><strong aria-hidden="true">9.</strong> Functions</a></li><li class="chapter-item expanded "><a href="Jobs-_0026-Signals.html" class="active"><strong aria-hidden="true">10.</strong> Jobs &amp; Signals</a></li><li class="chapter-item expanded "><a href="Arithmetic-Evaluation.html"><strong aria-hidden="true">11.</strong> Arithmetic Evaluation</a></li><li class="chapter-item expanded "><a href="Conditional-Expressions.html"><strong aria-hidden="true">12.</strong> Conditional Expressions</a></li><li class="chapter-item expanded "><a href="Prompt-Expansion.html"><strong aria-hidden="true">13.</strong> Prompt Expansion</a></li><li class="chapter-item expanded "><a href="Expansion.html"><strong aria-hidden="true">14.</strong> Expansion</a></li><li class="chapter-item expanded "><a href="Parameters.html"><strong aria-hidden="true">15.</strong> Parameters</a></li><li class="chapter-item expanded "><a href="Options.html"><strong aria-hidden="true">16.</strong> Options</a></li><li class="chapter-item expanded "><a href="Shell-Builtin-Commands.html"><strong aria-hidden="true">17.</strong> Shell Builtin Commands</a></li><li class="chapter-item expanded "><a href="Zsh-Line-Editor.html"><strong aria-hidden="true">18.</strong> Zsh Line Editor</a></li><li class="chapter-item expanded "><a href="Completion-Widgets.html"><strong aria-hidden="true">19.</strong> Completion Widgets</a></li><li class="chapter-item expanded "><a href="Completion-System.html"><strong aria-hidden="true">20.</strong> Completion System</a></li><li class="chapter-item expanded "><a href="Completion-Using-compctl.html"><strong aria-hidden="true">21.</strong> Completion Using compctl</a></li><li class="chapter-item expanded "><a href="Zsh-Modules.html"><strong aria-hidden="true">22.</strong> Zsh Modules</a></li><li class="chapter-item expanded "><a href="Calendar-Function-System.html"><strong aria-hidden="true">23.</strong> Calendar Function System</a></li><li class="chapter-item expanded "><a href="TCP-Function-System.html"><strong aria-hidden="true">24.</strong> TCP Function System</a></li><li class="chapter-item expanded "><a href="Zftp-Function-System.html"><strong aria-hidden="true">25.</strong> Zftp Function System</a></li><li class="chapter-item expanded "><a href="User-Contributions.html"><strong aria-hidden="true">26.</strong> User Contributions</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>
</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 Manual</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" name="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="#10-jobs--signals">10 Jobs &amp; Signals</a>
<ul>
<li><a href="#101-jobs">10.1 Jobs</a></li>
<li><a href="#102-signals">10.2 Signals</a></li>
</ul>
</li>
</ul>
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<p><span id="Jobs-_0026-Signals"></span>
<span id="Jobs-_0026-Signals-1"></span></p>
<h1 id="10-jobs--signals"><a class="header" href="#10-jobs--signals">10 Jobs &amp; Signals</a></h1>
<hr />
<p><span id="Jobs"></span></p>
<h2 id="101-jobs"><a class="header" href="#101-jobs">10.1 Jobs</a></h2>
<p><span id="index-jobs"></span>
<span id="index-MONITOR_002c-use-of"></span></p>
<p>If the <code>MONITOR</code> option is set, an interactive shell associates a <em>job</em>
with each pipeline. command, and assigns them small integer numbers.
When a job is started asynchronously with <code>&amp;</code>, the shell prints a line
to standard error which looks like:</p>
<div class="example">
<pre><code class="language-example">[1] 1234
</code></pre>
</div>
<p>indicating that the job which was started asynchronously was job number
1 and had one (top-level) process, whose process ID was 1234.</p>
<p>If a job is started with <code>&amp;|</code> or <code>&amp;!</code>, then that job is immediately
disowned. After startup, it to the job control features described here.</p>
<p>If you are running a job and wish to do something else you may hit the
key ^Z (control-Z) which sends a <code>TSTP</code> signal to the current job: this
key may be redefined by the <code>susp</code> option of the external <code>stty</code>
command. <span id="index-jobs_002c-suspending"></span>
<span id="index-suspending-jobs"></span> The shell will then normally
indicate that the job has been suspended, and print another prompt.
You can then manipulate the state of this job,
<span id="index-bg_002c-use-of"></span> putting it in the background
with the <code>bg</code> command, or run some other commands and then eventually
bring the job back into the foreground with
<span id="index-fg_002c-use-of"></span> the foreground command <code>fg</code>. A
^Z takes effect immediately and is like an interrupt in that pending
output and unread input are discarded when it is typed.</p>
<p>A job being run in the background will suspend if it tries to read from
the terminal.</p>
<p>Note that if the job running in the foreground is a shell function, then
suspending it will have the effect of causing the shell to fork. This is
necessary to separate the functions state from that of the parent shell
performing the job control, so that the latter can return to the command
line prompt. As a result, even if <code>fg</code> is used to continue the job the
function will no longer be part of the parent shell, and any variables
set by the function will not be visible in the parent shell. Thus the
behaviour is different from the case where the function was never
suspended. Zsh is different from many other shells in this regard.</p>
<p>One additional side effect is that use of <code>disown</code> with a job created by
suspending shell code in this fashion is delayed: the job can only be
disowned once any process started from the parent shell has terminated.
At that point, the disowned job disappears silently from the job list.</p>
<p>The same behaviour is found when the shell is executing code as the
right hand side of a pipeline or any complex shell construct such as
<code>if</code>, <code>for</code>, etc., in order that the entire block of code can be managed
as a single job. <span id="index-background-jobs_002c-I_002fO"></span>
<span id="index-jobs_002c-background_002c-I_002fO"></span> Background
jobs are normally allowed to produce output, but this can be disabled by
giving the command <code>stty tostop</code>. If you set this tty option, then
background jobs will suspend when they try to produce output like they
do when they try to read input.</p>
<p>When a command is suspended and continued later with the <code>fg</code> or <code>wait</code>
builtins, zsh restores tty modes that were in effect when it was
suspended. This (intentionally) does not apply if the command is
continued via <code>kill -CONT</code>, nor when it is continued with <code>bg</code>.</p>
<p><span id="index-jobs_002c-referring-to"></span>
<span id="index-referring-to-jobs"></span></p>
<p>There are several ways to refer to jobs in the shell. A job can be
referred to by the process ID of any process of the job or by one of the
following:</p>
<ul>
<li>
<p><code>%``number</code><br />
The job with the given number.</p>
</li>
<li>
<p><code>%``string</code><br />
The last job whose command line begins with <code>string</code>.</p>
</li>
<li>
<p><code>%?``string</code><br />
The last job whose command line contains <code>string</code>.</p>
</li>
<li>
<p><code>%%</code><br />
Current job.</p>
</li>
<li>
<p><code>%+</code><br />
Equivalent to <code>%%</code>.</p>
</li>
<li>
<p><code>%-</code><br />
Previous job.</p>
</li>
</ul>
<p>The shell learns immediately whenever a process changes state.
<span id="index-NOTIFY_002c-use-of"></span> It normally informs you
whenever a job becomes blocked so that no further progress is possible.
If the <code>NOTIFY</code> option is not set, it waits until just before it prints
a prompt before it informs you. All such notifications are sent directly
to the terminal, not to the standard output or standard error.</p>
<p>When the monitor mode is on, each background job that completes triggers
any trap set for <code>CHLD</code>.</p>
<p>When you try to leave the shell while jobs are running or suspended, you
will be warned that You have suspended (running) jobs. You may use the
<code>jobs</code> command to see what they are. If you do this or immediately try
to exit again, the shell will not warn you a second time; the suspended
jobs will be terminated, and the running jobs will be sent a <code>SIGHUP</code>
signal, if the <code>HUP</code> option is set.
<span id="index-HUP_002c-use-of"></span></p>
<p><span id="index-jobs_002c-disowning"></span>
<span id="index-disowning-jobs"></span>
<span id="index-disown_002c-use-of"></span></p>
<p>To avoid having the shell terminate the running jobs, either use the
nohup command (see man page nohup(1)) or the <code>disown</code> builtin.</p>
<hr />
<p><span id="Signals"></span></p>
<h2 id="102-signals"><a class="header" href="#102-signals">10.2 Signals</a></h2>
<p>The <code>INT</code> and <code>QUIT</code> signals for an invoked command are ignored if the
command is followed by <code>&amp;</code> and the <code>MONITOR</code> option is not active. The
shell itself always ignores the <code>QUIT</code> signal. Otherwise, signals have
the values inherited by the shell from its parent (but see the
<code>TRAP``NAL</code> special functions in <a href="Functions.html#Functions">Functions</a>).</p>
<p><span id="index-exiting-shell_002c-and-asynchronous-jobs"></span>
<span id="index-asynchronous-jobs_002c-and-exiting-shell"></span>
<span id="index-jobs_002c-asynchronous_002c-and-exiting-shell"></span></p>
<p>Certain jobs are run asynchronously by the shell other than those
explicitly put into the background; even in cases where the shell would
usually wait for such jobs, an explicit <code>exit</code> command or exit due to
the option <code>ERR_EXIT</code> will cause the shell to exit without waiting.
Examples of such asynchronous jobs are process substitution, see
<a href="Expansion.html#Process-Substitution">Process Substitution</a>, and the
handler processes for multios, see the section Multios in
<a href="Redirection.html#Redirection">Redirection</a>.</p>
<hr />
<p>This document was generated on <em>February 15, 2020</em> using
<a href="http://www.nongnu.org/texi2html/"><em>texi2html 5.0</em></a>.<br />
Zsh version 5.8, released on February 14, 2020.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="Functions.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="Arithmetic-Evaluation.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="Functions.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="Arithmetic-Evaluation.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>
<!-- Livereload script (if served using the cli tool) -->
<script type="text/javascript">
var socket = new WebSocket("ws://localhost:3000/__livereload");
socket.onmessage = function (event) {
if (event.data === "reload") {
socket.close();
location.reload();
}
};
window.onbeforeunload = function() {
socket.close();
}
</script>
<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>

2819
book/Options.html Normal file

File diff suppressed because it is too large Load Diff

2013
book/Parameters.html Normal file

File diff suppressed because it is too large Load Diff

751
book/Prompt-Expansion.html Normal file
View File

@ -0,0 +1,751 @@
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Prompt Expansion - Zsh Manual</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 -->
</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 "><a href="The-Z-Shell-Manual.html"><strong aria-hidden="true">1.</strong> The Z Shell Manual</a></li><li class="chapter-item expanded "><a href="Introduction.html"><strong aria-hidden="true">2.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="Roadmap.html"><strong aria-hidden="true">3.</strong> Roadmap</a></li><li class="chapter-item expanded "><a href="Invocation.html"><strong aria-hidden="true">4.</strong> Invocation</a></li><li class="chapter-item expanded "><a href="Files.html"><strong aria-hidden="true">5.</strong> Files</a></li><li class="chapter-item expanded "><a href="Shell-Grammar.html"><strong aria-hidden="true">6.</strong> Shell Grammar</a></li><li class="chapter-item expanded "><a href="Redirection.html"><strong aria-hidden="true">7.</strong> Redirection</a></li><li class="chapter-item expanded "><a href="Command-Execution.html"><strong aria-hidden="true">8.</strong> Command Execution</a></li><li class="chapter-item expanded "><a href="Functions.html"><strong aria-hidden="true">9.</strong> Functions</a></li><li class="chapter-item expanded "><a href="Jobs-_0026-Signals.html"><strong aria-hidden="true">10.</strong> Jobs &amp; Signals</a></li><li class="chapter-item expanded "><a href="Arithmetic-Evaluation.html"><strong aria-hidden="true">11.</strong> Arithmetic Evaluation</a></li><li class="chapter-item expanded "><a href="Conditional-Expressions.html"><strong aria-hidden="true">12.</strong> Conditional Expressions</a></li><li class="chapter-item expanded "><a href="Prompt-Expansion.html" class="active"><strong aria-hidden="true">13.</strong> Prompt Expansion</a></li><li class="chapter-item expanded "><a href="Expansion.html"><strong aria-hidden="true">14.</strong> Expansion</a></li><li class="chapter-item expanded "><a href="Parameters.html"><strong aria-hidden="true">15.</strong> Parameters</a></li><li class="chapter-item expanded "><a href="Options.html"><strong aria-hidden="true">16.</strong> Options</a></li><li class="chapter-item expanded "><a href="Shell-Builtin-Commands.html"><strong aria-hidden="true">17.</strong> Shell Builtin Commands</a></li><li class="chapter-item expanded "><a href="Zsh-Line-Editor.html"><strong aria-hidden="true">18.</strong> Zsh Line Editor</a></li><li class="chapter-item expanded "><a href="Completion-Widgets.html"><strong aria-hidden="true">19.</strong> Completion Widgets</a></li><li class="chapter-item expanded "><a href="Completion-System.html"><strong aria-hidden="true">20.</strong> Completion System</a></li><li class="chapter-item expanded "><a href="Completion-Using-compctl.html"><strong aria-hidden="true">21.</strong> Completion Using compctl</a></li><li class="chapter-item expanded "><a href="Zsh-Modules.html"><strong aria-hidden="true">22.</strong> Zsh Modules</a></li><li class="chapter-item expanded "><a href="Calendar-Function-System.html"><strong aria-hidden="true">23.</strong> Calendar Function System</a></li><li class="chapter-item expanded "><a href="TCP-Function-System.html"><strong aria-hidden="true">24.</strong> TCP Function System</a></li><li class="chapter-item expanded "><a href="Zftp-Function-System.html"><strong aria-hidden="true">25.</strong> Zftp Function System</a></li><li class="chapter-item expanded "><a href="User-Contributions.html"><strong aria-hidden="true">26.</strong> User Contributions</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>
</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 Manual</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" name="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="#13-prompt-expansion">13 Prompt Expansion</a>
<ul>
<li><a href="#131-expansion-of-prompt-sequences">13.1 Expansion of Prompt Sequences</a></li>
<li><a href="#132-simple-prompt-escapes">13.2 Simple Prompt Escapes</a>
<ul>
<li><a href="#1321-special-characters">13.2.1 Special characters</a></li>
<li><a href="#1322-login-information">13.2.2 Login information</a></li>
<li><a href="#1323-shell-state">13.2.3 Shell state</a></li>
<li><a href="#1324-date-and-time">13.2.4 Date and time</a></li>
<li><a href="#1325-visual-effects">13.2.5 Visual effects</a></li>
</ul>
</li>
<li><a href="#133-conditional-substrings-in-prompts">13.3 Conditional Substrings in Prompts</a></li>
</ul>
</li>
</ul>
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<p><span id="Prompt-Expansion"></span>
<span id="Prompt-Expansion-1"></span></p>
<h1 id="13-prompt-expansion"><a class="header" href="#13-prompt-expansion">13 Prompt Expansion</a></h1>
<hr />
<p><span id="Expansion-of-Prompt-Sequences"></span></p>
<h2 id="131-expansion-of-prompt-sequences"><a class="header" href="#131-expansion-of-prompt-sequences">13.1 Expansion of Prompt Sequences</a></h2>
<p><span id="index-prompt-expansion"></span>
<span id="index-expansion_002c-prompt"></span></p>
<p>Prompt sequences undergo a special form of expansion. This type of
expansion is also available using the <code>-P</code> option to the <code>print</code>
builtin.</p>
<p><span id="index-PROMPT_005fSUBST_002c-use-of"></span></p>
<p>If the <code>PROMPT_SUBST</code> option is set, the prompt string is first
subjected to <em>parameter expansion</em>, <em>command substitution</em> and
<em>arithmetic expansion</em>. See <a href="Expansion.html#Expansion">Expansion</a>.</p>
<p>Certain escape sequences may be recognised in the prompt string.</p>
<p><span id="index-PROMPT_005fBANG_002c-use-of"></span></p>
<p>If the <code>PROMPT_BANG</code> option is set, a <code>!</code> in the prompt is replaced by
the current history event number. A literal <code>!</code> may then be
represented as <code>!!</code>.</p>
<p><span id="index-PROMPT_005fPERCENT_002c-use-of"></span></p>
<p>If the <code>PROMPT_PERCENT</code> option is set, certain escape sequences that
start with <code>%</code> are expanded. Many escapes are followed by a single
character, although some of these take an optional integer argument that
should appear between the <code>%</code> and the next character of the sequence.
More complicated escape sequences are available to provide conditional
expansion.</p>
<hr />
<p><span id="Simple-Prompt-Escapes"></span></p>
<h2 id="132-simple-prompt-escapes"><a class="header" href="#132-simple-prompt-escapes">13.2 Simple Prompt Escapes</a></h2>
<hr />
<p><span id="Special-characters"></span></p>
<h3 id="1321-special-characters"><a class="header" href="#1321-special-characters">13.2.1 Special characters</a></h3>
<ul>
<li>
<p><code>%%</code><br />
A <code>%</code>.</p>
</li>
<li>
<p><code>%)</code><br />
A <code>)</code>.</p>
</li>
</ul>
<hr />
<p><span id="Login-information"></span></p>
<h3 id="1322-login-information"><a class="header" href="#1322-login-information">13.2.2 Login information</a></h3>
<ul>
<li>
<p><code>%l</code><br />
The line (tty) the user is logged in on, without <code>/dev/</code> prefix.
If the name starts with <code>/dev/tty</code>, that prefix is stripped.</p>
</li>
<li>
<p><code>%M</code><br />
The full machine hostname.</p>
</li>
<li>
<p><code>%m</code><br />
The hostname up to the first <code>.</code>. An integer may follow the <code>%</code>
to specify how many components of the hostname are desired. With a
negative integer, trailing components of the hostname are shown.</p>
</li>
<li>
<p><code>%n</code><br />
<code>$USERNAME</code>.</p>
</li>
<li>
<p><code>%y</code><br />
The line (tty) the user is logged in on, without <code>/dev/</code> prefix.
This does not treat <code>/dev/tty</code> names specially.</p>
</li>
</ul>
<hr />
<p><span id="Shell-state"></span></p>
<h3 id="1323-shell-state"><a class="header" href="#1323-shell-state">13.2.3 Shell state</a></h3>
<ul>
<li>
<p><code>%#</code><br />
A <code>#</code> if the shell is running with privileges, a <code>%</code> if not.
Equivalent to <code>%(!.#.%%)</code>. The definition of privileged, for
these purposes, is that either the effective user ID is zero, or, if
POSIX.1e capabilities are supported, that capability vectors.</p>
</li>
<li>
<p><code>%?</code><br />
The return status of the last command executed just before the
prompt.</p>
</li>
<li>
<p><code>%_</code><br />
The status of the parser, i.e. the shell constructs (like <code>if</code> and
<code>for</code>) that have been started on the command line. If given an
integer number that many strings will be printed; zero or negative
or no integer means print as many as there are. This is most useful
in prompts <code>PS2</code> for continuation lines and <code>PS4</code> for debugging with
the <code>XTRACE</code> option; in the latter case it will also work
non-interactively.</p>
</li>
<li>
<p><code>%^</code><br />
The status of the parser in reverse. This is the same as <code>%_</code>
other than the order of strings. It is often used in <code>RPS2</code>.</p>
</li>
<li>
<p><code>%d</code><br />
<code>%/</code><br />
Current working directory. If an integer follows the <code>%</code>, it
specifies a number of trailing components of the current working
directory to show; zero means the whole path. A negative integer
specifies leading components, i.e. <code>%-1d</code> specifies the first
component.</p>
</li>
<li>
<p><code>%~</code><br />
As <code>%d</code> and <code>%/</code>, but if the current working directory starts with
<code>$HOME</code>, that part is replaced by a <code>~</code>. Furthermore, if it has a
named directory as its prefix, that part is replaced by a <code>~</code>
followed by the name of the directory, but only if the result is
shorter than the full path; <a href="Expansion.html#Filename-Expansion">Filename
Expansion</a>.</p>
</li>
<li>
<p><code>%e</code><br />
Evaluation depth of the current sourced file, shell function, or
<code>eval</code>. This is incremented or decremented every time the value of
<code>%N</code> is set or reverted to a previous value, respectively. This is
most useful for debugging as part of <code>$PS4</code>.</p>
</li>
<li>
<p><code>%h</code><br />
<code>%!</code><br />
Current history event number.</p>
</li>
<li>
<p><code>%i</code><br />
The line number currently being executed in the script, sourced
file, or shell function given by <code>%N</code>. This is most useful for
debugging as part of <code>$PS4</code>.</p>
</li>
<li>
<p><code>%I</code><br />
The line number currently being executed in the file <code>%x</code>. This is
similar to <code>%i</code>, but the line number is always a line number in the
file where the code was defined, even if the code is a shell
function.</p>
</li>
<li>
<p><code>%j</code><br />
The number of jobs.</p>
</li>
<li>
<p><code>%L</code><br />
The current value of <code>$SHLVL</code>.</p>
</li>
<li>
<p><code>%N</code><br />
The name of the script, sourced file, or shell function that zsh is
currently executing, whichever was started most recently. If there
is none, this is equivalent to the parameter <code>$0</code>. An integer may
follow the <code>%</code> to specify a number of trailing path components to
show; zero means the full path. A negative integer specifies leading
components.</p>
</li>
<li>
<p><code>%x</code><br />
The name of the file containing the source code currently being
executed. This behaves as <code>%N</code> except that function and eval command
names are not shown, instead the file where they were defined.</p>
</li>
<li>
<p><code>%c</code><br />
<code>%.</code><br />
<code>%C</code><br />
Trailing component of the current working directory. An integer may
follow the <code>%</code> to get more than one component. Unless <code>%C</code> is
used, tilde contraction is performed first. These are deprecated as
<code>%c</code> and <code>%C</code> are equivalent to <code>%1~</code> and <code>%1/</code>, respectively, while
explicit positive integers have the same effect as for the latter
two sequences.</p>
</li>
</ul>
<hr />
<p><span id="Date-and-time"></span></p>
<h3 id="1324-date-and-time"><a class="header" href="#1324-date-and-time">13.2.4 Date and time</a></h3>
<ul>
<li>
<p><code>%D</code><br />
The date in <code>yy``-``mm``-``dd</code> format.</p>
</li>
<li>
<p><code>%T</code><br />
Current time of day, in 24-hour format.</p>
</li>
<li>
<p><code>%t</code><br />
<code>%@</code><br />
Current time of day, in 12-hour, am/pm format.</p>
</li>
<li>
<p><code>%*</code><br />
Current time of day in 24-hour format, with seconds.</p>
</li>
<li>
<p><code>%w</code><br />
The date in <code>day``-``dd</code> format.</p>
</li>
<li>
<p><code>%W</code><br />
The date in <code>mm``/``dd``/``yy</code> format.</p>
</li>
<li>
<p><code>%D{``string``}</code><br />
<code>string</code> is formatted using the <code>strftime</code> function. See man page
strftime(3) for more details. Various zsh extensions provide numbers
with no leading zero or space if the number is a single digit:</p>
<ul>
<li>
<p><code>%f</code><br />
a day of the month</p>
</li>
<li>
<p><code>%K</code><br />
the hour of the day on the 24-hour clock</p>
</li>
<li>
<p><code>%L</code><br />
the hour of the day on the 12-hour clock</p>
</li>
</ul>
<p>In addition, if the system supports the POSIX <code>gettimeofday</code> system
call, <code>%.</code> provides decimal fractions of a second since the epoch
with leading zeroes. By default three decimal places are provided,
but a number of digits up to 9 may be given following the <code>%</code>; hence
<code>%6.</code> outputs microseconds, and <code>%9.</code> outputs nanoseconds. (The
latter requires a nanosecond-precision <code>clock_gettime</code>; systems
lacking this will return a value multiplied by the appropriate power
of 10.) A typical example of this is the format <code>%D{%H:%M:%S.%.}</code>.</p>
<p>The GNU extension <code>%N</code> is handled as a synonym for <code>%9.</code>.</p>
<p>Additionally, the GNU extension that a <code>-</code> between the <code>%</code> and the
format character causes a leading zero or space to be stripped is
handled directly by the shell for the format characters <code>d</code>, <code>f</code>,
<code>H</code>, <code>k</code>, <code>l</code>, <code>m</code>, <code>M</code>, <code>S</code> and <code>y</code>; any other format characters
are provided to the systems strftime(3) with any leading <code>-</code>
present, so the handling is system dependent. Further GNU (or other)
extensions are also passed to strftime(3) and may work if the system
supports them.</p>
</li>
</ul>
<hr />
<p><span id="Visual-effects"></span></p>
<h3 id="1325-visual-effects"><a class="header" href="#1325-visual-effects">13.2.5 Visual effects</a></h3>
<ul>
<li>
<p><code>%B</code> (<code>%b</code>)<br />
Start (stop) boldface mode.</p>
</li>
<li>
<p><code>%E</code><br />
Clear to end of line.</p>
</li>
<li>
<p><code>%U</code> (<code>%u</code>)<br />
Start (stop) underline mode.</p>
</li>
<li>
<p><code>%S</code> (<code>%s</code>)<br />
Start (stop) standout mode.</p>
</li>
<li>
<p><code>%F</code> (<code>%f</code>)<br />
Start (stop) using a different foreground colour, if supported by
the terminal. The colour may be specified two ways: either as a
numeric argument, as normal, or by a sequence in braces following
the <code>%F</code>, for example <code>%F{red}</code>. In the latter case the values
allowed are as described for the <code>fg</code> <code>zle_highlight</code> attribute;
<a href="Zsh-Line-Editor.html#Character-Highlighting">Character
Highlighting</a>. This
means that numeric colours are allowed in the second format also.</p>
</li>
<li>
<p><code>%K</code> (<code>%k</code>)<br />
Start (stop) using a different bacKground colour. The syntax is
identical to that for <code>%F</code> and <code>%f</code>.</p>
</li>
<li>
<p><code>%{</code>...<code>%}</code><br />
Include a string as a literal escape sequence. The string within the
braces should not change the cursor position. Brace pairs can nest.</p>
<p>A positive numeric argument between the <code>%</code> and the <code>{</code> is treated
as described for <code>%G</code> below.</p>
</li>
<li>
<p><code>%G</code><br />
Within a <code>%{</code>...<code>%}</code> sequence, include a glitch: that is, assume
that a single character width will be output. This is useful when
outputting characters that otherwise cannot be correctly handled by
the shell, such as the alternate character set on some terminals.
The characters in question can be included within a <code>%{</code>...<code>%}</code>
sequence together with the appropriate number of <code>%G</code> sequences to
indicate the correct width. An integer between the <code>%</code> and <code>G</code>
indicates a character width other than one. Hence <code>%{``seq``%2G%}</code>
outputs <code>seq</code> and assumes it takes up the width of two standard
characters.</p>
<p>Multiple uses of <code>%G</code> accumulate in the obvious fashion; the
position of the <code>%G</code> is unimportant. Negative integers are not
handled.</p>
<p>Note that when prompt truncation is in use it is advisable to divide
up output into single characters within each <code>%{</code>...<code>%}</code> group so
that the correct truncation point can be found.</p>
</li>
</ul>
<hr />
<p><span id="Conditional-Substrings-in-Prompts"></span></p>
<h2 id="133-conditional-substrings-in-prompts"><a class="header" href="#133-conditional-substrings-in-prompts">13.3 Conditional Substrings in Prompts</a></h2>
<ul>
<li>
<p><code>%v</code><br />
<span id="index-psvar_002c-use-of"></span></p>
<p>The value of the first element of the <code>psvar</code> array parameter.
Following the <code>%</code> with an integer gives that element of the array.
Negative integers count from the end of the array.</p>
</li>
<li>
<p><code>%(``x``.``true-text``.``false-text``)</code><br />
Specifies a ternary expression. The character following the <code>x</code> is
arbitrary; the same character is used to separate the text for the
true result from that for the false result. This separator may
not appear in the <code>true-text</code>, except as part of a %-escape
sequence. A <code>)</code> may appear in the <code>false-text</code> as <code>%)</code>.
<code>true-text</code> and <code>false-text</code> may both contain arbitrarily-nested
escape sequences, including further ternary expressions.</p>
<p>The left parenthesis may be preceded or followed by a positive
integer <code>n</code>, which defaults to zero. A negative integer will be
multiplied by -1, except as noted below for <code>l</code>. The test
character <code>x</code> may be any of the following:</p>
<ul>
<li>
<p><code>!</code><br />
True if the shell is running with privileges.</p>
</li>
<li>
<p><code>#</code><br />
True if the effective uid of the current process is <code>n</code>.</p>
</li>
<li>
<p><code>?</code><br />
True if the exit status of the last command was <code>n</code>.</p>
</li>
<li>
<p><code>_</code><br />
True if at least <code>n</code> shell constructs were started.</p>
</li>
<li>
<p><code>C</code><br />
<code>/</code><br />
True if the current absolute path has at least <code>n</code> elements
relative to the root directory, hence <code>/</code> is counted as 0
elements.</p>
</li>
<li>
<p><code>c</code><br />
<code>.</code><br />
<code>~</code><br />
True if the current path, with prefix replacement, has at least
<code>n</code> elements relative to the root directory, hence <code>/</code> is
counted as 0 elements.</p>
</li>
<li>
<p><code>D</code><br />
True if the month is equal to <code>n</code> (January = 0).</p>
</li>
<li>
<p><code>d</code><br />
True if the day of the month is equal to <code>n</code>.</p>
</li>
<li>
<p><code>e</code><br />
True if the evaluation depth is at least <code>n</code>.</p>
</li>
<li>
<p><code>g</code><br />
True if the effective gid of the current process is <code>n</code>.</p>
</li>
<li>
<p><code>j</code><br />
True if the number of jobs is at least <code>n</code>.</p>
</li>
<li>
<p><code>L</code><br />
True if the <code>SHLVL</code> parameter is at least <code>n</code>.</p>
</li>
<li>
<p><code>l</code><br />
True if at least <code>n</code> characters have already been printed on the
current line. When <code>n</code> is negative, true if at least
<code>abs``(``n``)</code> characters remain before the opposite margin
(thus the left margin for <code>RPROMPT</code>).</p>
</li>
<li>
<p><code>S</code><br />
True if the <code>SECONDS</code> parameter is at least <code>n</code>.</p>
</li>
<li>
<p><code>T</code><br />
True if the time in hours is equal to <code>n</code>.</p>
</li>
<li>
<p><code>t</code><br />
True if the time in minutes is equal to <code>n</code>.</p>
</li>
<li>
<p><code>v</code><br />
True if the array <code>psvar</code> has at least <code>n</code> elements.</p>
</li>
<li>
<p><code>V</code><br />
True if element <code>n</code> of the array <code>psvar</code> is set and non-empty.</p>
</li>
<li>
<p><code>w</code><br />
True if the day of the week is equal to <code>n</code> (Sunday = 0).</p>
</li>
</ul>
</li>
<li>
<p><code>%&lt;``string``&lt;</code><br />
<code>%&gt;``string``&gt;</code><br />
<code>%[``xstring``]</code><br />
Specifies truncation behaviour for the remainder of the prompt
string. The third, deprecated, form is equivalent to
<code>%``xstringx</code>, i.e. <code>x</code> may be <code>&lt;</code> or <code>&gt;</code>. The <code>string</code>
will be displayed in place of the truncated portion of any string;
note this does not undergo prompt expansion.</p>
<p>The numeric argument, which in the third form may appear immediately
after the <code>[</code>, specifies the maximum permitted length of the
various strings that can be displayed in the prompt. In the first
two forms, this numeric argument may be negative, in which case the
truncation length is determined by subtracting the absolute value of
the numeric argument from the number of character positions
remaining on the current prompt line. If this results in a zero or
negative length, a length of 1 is used. In other words, a negative
argument arranges that after truncation at least <code>n</code> characters
remain before the right margin (left margin for <code>RPROMPT</code>).</p>
<p>The forms with <code>&lt;</code> truncate at the left of the string, and the
forms with <code>&gt;</code> truncate at the right of the string. For example,
if the current directory is <code>/home/pike</code>, the prompt <code>%8&lt;..&lt;%/</code>
will expand to <code>..e/pike</code>. In this string, the terminating
character (<code>&lt;</code>, <code>&gt;</code> or <code>]</code>), or in fact any character, may be
quoted by a preceding <code>\</code>; note when using <code>print -P</code>, however,
that this must be doubled as the string is also subject to standard
<code>print</code> processing, in addition to any backslashes removed by a
double quoted string: the worst case is therefore <code>print -P &quot;%&lt;\\&lt;&lt;...&quot;</code>.</p>
<p>If the <code>string</code> is longer than the specified truncation length, it
will appear in full, completely replacing the truncated string.</p>
<p>The part of the prompt string to be truncated runs to the end of the
string, or to the end of the next enclosing group of the <code>%(</code>
construct, or to the next truncation encountered at the same
grouping level (i.e. truncations inside a <code>%(</code> are separate),
which ever comes first. In particular, a truncation with argument
zero (e.g., <code>%&lt;&lt;</code>) marks the end of the range of the string to be
truncated while turning off truncation from there on. For example,
the prompt <code>%10&lt;...&lt;%~%&lt;&lt;%# </code> will print a truncated
representation of the current directory, followed by a <code>%</code> or
<code>#</code>, followed by a space. Without the <code>%&lt;&lt;</code>, those two
characters would be included in the string to be truncated. Note
that <code>%-0&lt;&lt;</code> is not equivalent to <code>%&lt;&lt;</code> but specifies that the
prompt is truncated at the right margin.</p>
<p>Truncation applies only within each individual line of the prompt,
as delimited by embedded newlines (if any). If the total length of
any line of the prompt after truncation is greater than the terminal
width, or if the part to be truncated contains embedded newlines,
truncation behavior is undefined and may change in a future version
of the shell. Use <code>%-``n``(l.``true-text``.``false-text``)</code> to
remove parts of the prompt when the available space is less than
<code>n</code>.</p>
</li>
</ul>
<hr />
<p>This document was generated on <em>February 15, 2020</em> using
<a href="http://www.nongnu.org/texi2html/"><em>texi2html 5.0</em></a>.<br />
Zsh version 5.8, released on February 14, 2020.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="Conditional-Expressions.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="Expansion.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="Conditional-Expressions.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="Expansion.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>
<!-- Livereload script (if served using the cli tool) -->
<script type="text/javascript">
var socket = new WebSocket("ws://localhost:3000/__livereload");
socket.onmessage = function (event) {
if (event.data === "reload") {
socket.close();
location.reload();
}
};
window.onbeforeunload = function() {
socket.close();
}
</script>
<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>

620
book/Redirection.html Normal file
View File

@ -0,0 +1,620 @@
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Redirection - Zsh Manual</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 -->
</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 "><a href="The-Z-Shell-Manual.html"><strong aria-hidden="true">1.</strong> The Z Shell Manual</a></li><li class="chapter-item expanded "><a href="Introduction.html"><strong aria-hidden="true">2.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="Roadmap.html"><strong aria-hidden="true">3.</strong> Roadmap</a></li><li class="chapter-item expanded "><a href="Invocation.html"><strong aria-hidden="true">4.</strong> Invocation</a></li><li class="chapter-item expanded "><a href="Files.html"><strong aria-hidden="true">5.</strong> Files</a></li><li class="chapter-item expanded "><a href="Shell-Grammar.html"><strong aria-hidden="true">6.</strong> Shell Grammar</a></li><li class="chapter-item expanded "><a href="Redirection.html" class="active"><strong aria-hidden="true">7.</strong> Redirection</a></li><li class="chapter-item expanded "><a href="Command-Execution.html"><strong aria-hidden="true">8.</strong> Command Execution</a></li><li class="chapter-item expanded "><a href="Functions.html"><strong aria-hidden="true">9.</strong> Functions</a></li><li class="chapter-item expanded "><a href="Jobs-_0026-Signals.html"><strong aria-hidden="true">10.</strong> Jobs &amp; Signals</a></li><li class="chapter-item expanded "><a href="Arithmetic-Evaluation.html"><strong aria-hidden="true">11.</strong> Arithmetic Evaluation</a></li><li class="chapter-item expanded "><a href="Conditional-Expressions.html"><strong aria-hidden="true">12.</strong> Conditional Expressions</a></li><li class="chapter-item expanded "><a href="Prompt-Expansion.html"><strong aria-hidden="true">13.</strong> Prompt Expansion</a></li><li class="chapter-item expanded "><a href="Expansion.html"><strong aria-hidden="true">14.</strong> Expansion</a></li><li class="chapter-item expanded "><a href="Parameters.html"><strong aria-hidden="true">15.</strong> Parameters</a></li><li class="chapter-item expanded "><a href="Options.html"><strong aria-hidden="true">16.</strong> Options</a></li><li class="chapter-item expanded "><a href="Shell-Builtin-Commands.html"><strong aria-hidden="true">17.</strong> Shell Builtin Commands</a></li><li class="chapter-item expanded "><a href="Zsh-Line-Editor.html"><strong aria-hidden="true">18.</strong> Zsh Line Editor</a></li><li class="chapter-item expanded "><a href="Completion-Widgets.html"><strong aria-hidden="true">19.</strong> Completion Widgets</a></li><li class="chapter-item expanded "><a href="Completion-System.html"><strong aria-hidden="true">20.</strong> Completion System</a></li><li class="chapter-item expanded "><a href="Completion-Using-compctl.html"><strong aria-hidden="true">21.</strong> Completion Using compctl</a></li><li class="chapter-item expanded "><a href="Zsh-Modules.html"><strong aria-hidden="true">22.</strong> Zsh Modules</a></li><li class="chapter-item expanded "><a href="Calendar-Function-System.html"><strong aria-hidden="true">23.</strong> Calendar Function System</a></li><li class="chapter-item expanded "><a href="TCP-Function-System.html"><strong aria-hidden="true">24.</strong> TCP Function System</a></li><li class="chapter-item expanded "><a href="Zftp-Function-System.html"><strong aria-hidden="true">25.</strong> Zftp Function System</a></li><li class="chapter-item expanded "><a href="User-Contributions.html"><strong aria-hidden="true">26.</strong> User Contributions</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>
</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 Manual</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" name="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="#7-redirection">7 Redirection</a>
<ul>
<li><a href="#71-opening-file-descriptors-using-parameters">7.1 Opening file descriptors using parameters</a></li>
<li><a href="#72-multios">7.2 Multios</a></li>
<li><a href="#73-redirections-with-no-command">7.3 Redirections with no command</a></li>
</ul>
</li>
</ul>
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<p><span id="Redirection"></span> <span id="Redirection-1"></span></p>
<h1 id="7-redirection"><a class="header" href="#7-redirection">7 Redirection</a></h1>
<p><span id="index-redirection"></span>
<span id="index-file-descriptors"></span>
<span id="index-descriptors_002c-file"></span></p>
<p>If a command is followed by <code>&amp;</code> and job control is not active, then the
default standard input for the command is the empty file <code>/dev/null</code>.
Otherwise, the environment for the execution of a command contains the
file descriptors of the invoking shell as modified by input/output
specifications.</p>
<p>The following may appear anywhere in a simple command or may precede or
follow a complex command. Expansion occurs before <code>word</code> or <code>digit</code> is
used except as noted below. If the result of substitution on <code>word</code>
produces more than one filename, redirection occurs for each separate
filename in turn.</p>
<ul>
<li>
<p><code>&lt;</code> <code>word</code><br />
Open file <code>word</code> for reading as standard input. It is an error to
open a file in this fashion if it does not exist.</p>
</li>
<li>
<p><code>&lt;&gt;</code> <code>word</code><br />
Open file <code>word</code> for reading and writing as standard input. If the
file does not exist then it is created.</p>
</li>
<li>
<p><code>&gt;</code> <code>word</code><br />
Open file <code>word</code> for writing as standard output. If the file does
not exist then it is created. If the file exists, and the <code>CLOBBER</code>
option is unset, this causes an error; otherwise, it is truncated to
zero length.</p>
</li>
<li>
<p><code>&gt;|</code> <code>word</code><br />
<code>&gt;!</code> <code>word</code><br />
Same as <code>&gt;</code>, except that the file is truncated to zero length if it
exists, regardless of <code>CLOBBER</code>.</p>
</li>
<li>
<p><code>&gt;&gt;</code> <code>word</code><br />
Open file <code>word</code> for writing in append mode as standard output. If
the file does not exist, and the <code>CLOBBER</code> and <code>APPEND_CREATE</code>
options are both unset, this causes an error; otherwise, the file is
created.</p>
</li>
<li>
<p><code>&gt;&gt;|</code> <code>word</code><br />
<code>&gt;&gt;!</code> <code>word</code><br />
Same as <code>&gt;&gt;</code>, except that the file is created if it does not exist,
regardless of <code>CLOBBER</code> and <code>APPEND_CREATE</code>.</p>
</li>
<li>
<p><code>&lt;&lt;</code>[<code>-</code>] <code>word</code><br />
The shell input is read up to a line that is the same as <code>word</code>, or
to an end-of-file. No parameter expansion, command substitution or
filename generation is performed on <code>word</code>. The resulting document,
called a <em>here-document</em>, becomes the standard input.</p>
<p>If any character of <code>word</code> is quoted with single or double quotes or
a <code>\</code>, no interpretation is placed upon the characters of the
document. Otherwise, parameter and command substitution occurs,
<code>\</code> followed by a newline is removed, and <code>\</code> must be used
to quote the characters <code>\</code>, <code>$</code>, <code></code> and the first character
of <code>word</code>.</p>
<p>Note that <code>word</code> itself does not undergo shell expansion. Backquotes
in <code>word</code> do not have their usual effect; instead they behave
similarly to double quotes, except that the backquotes themselves
are passed through unchanged. (This information is given for
completeness and it is not recommended that backquotes be used.)
Quotes in the form <code>$``...``</code> have their standard effect of
expanding backslashed references to special characters.</p>
<p>If <code>&lt;&lt;-</code> is used, then all leading tabs are stripped from <code>word</code> and
from the document.</p>
</li>
<li>
<p><code>&lt;&lt;&lt;</code> <code>word</code><br />
Perform shell expansion on <code>word</code> and pass the result to standard
input. This is known as a <em>here-string</em>. Compare the use of <code>word</code>
in here-documents above, where <code>word</code> does not undergo shell
expansion.</p>
</li>
<li>
<p><code>&lt;&amp;</code> <code>number</code><br />
<code>&gt;&amp;</code> <code>number</code><br />
The standard input/output is duplicated from file descriptor
<code>number</code> (see man page dup2(2)).</p>
</li>
<li>
<p><code>&lt;&amp; -</code><br />
<code>&gt;&amp; -</code><br />
Close the standard input/output.</p>
</li>
<li>
<p><code>&lt;&amp; p</code><br />
<code>&gt;&amp; p</code><br />
The input/output from/to the coprocess is moved to the standard
input/output.</p>
</li>
<li>
<p><code>&gt;&amp;</code> <code>word</code><br />
<code>&amp;&gt;</code> <code>word</code><br />
(Except where <code>&gt;&amp;</code> <code>word</code> matches one of the above syntaxes;
<code>&amp;&gt;</code> can always be used to avoid this ambiguity.) Redirects
both standard output and standard error (file descriptor 2) in the
manner of <code>&gt;</code> <code>word</code>. Note that this does <em>not</em> have the same
effect as <code>&gt;</code> <code>word</code> <code>2&gt;&amp;1</code> in the presence of multios (see the
section below).</p>
</li>
<li>
<p><code>&gt;&amp;|</code> <code>word</code><br />
<code>&gt;&amp;!</code> <code>word</code><br />
<code>&amp;&gt;|</code> <code>word</code><br />
<code>&amp;&gt;!</code> <code>word</code><br />
Redirects both standard output and standard error (file descriptor</p>
<ol start="2">
<li>in the manner of <code>&gt;|</code> <code>word</code>.</li>
</ol>
</li>
<li>
<p><code>&gt;&gt;&amp;</code> <code>word</code><br />
<code>&amp;&gt;&gt;</code> <code>word</code><br />
Redirects both standard output and standard error (file descriptor</p>
<ol start="2">
<li>in the manner of <code>&gt;&gt;</code> <code>word</code>.</li>
</ol>
</li>
<li>
<p><code>&gt;&gt;&amp;|</code> <code>word</code><br />
<code>&gt;&gt;&amp;!</code> <code>word</code><br />
<code>&amp;&gt;&gt;|</code> <code>word</code><br />
<code>&amp;&gt;&gt;!</code> <code>word</code><br />
Redirects both standard output and standard error (file descriptor</p>
<ol start="2">
<li>in the manner of <code>&gt;&gt;|</code> <code>word</code>.</li>
</ol>
</li>
</ul>
<p>If one of the above is preceded by a digit, then the file descriptor
referred to is that specified by the digit instead of the default 0 or</p>
<ol>
<li>The order in which redirections are specified is significant. The
shell evaluates each redirection in terms of the (<em>file descriptor</em>,
<em>file</em>) association at the time of evaluation. For example:</li>
</ol>
<blockquote>
<p>... <code>1&gt;``fname</code> <code>2&gt;&amp;1</code></p>
</blockquote>
<p>first associates file descriptor 1 with file <code>fname</code>. It then associates
file descriptor 2 with the file associated with file descriptor 1 (that
is, <code>fname</code>). If the order of redirections were reversed, file
descriptor 2 would be associated with the terminal (assuming file
descriptor 1 had been) and then file descriptor 1 would be associated
with file <code>fname</code>.</p>
<p>The <code>|&amp;</code> command separator described in <a href="Shell-Grammar.html#Simple-Commands-_0026-Pipelines">Simple Commands &amp;
Pipelines</a> is a
shorthand for <code>2&gt;&amp;1 |</code>.</p>
<p>The various forms of process substitution, <code>&lt;(``list``)</code>, and
<code>=(``list``)</code> for input and <code>&gt;(``list``)</code> for output, are often
used together with redirection. For example, if <code>word</code> in an output
redirection is of the form <code>&gt;(``list``)</code> then the output is piped to
the command represented by <code>list</code>. See <a href="Expansion.html#Process-Substitution">Process
Substitution</a>.</p>
<hr />
<p><span id="Opening-file-descriptors-using-parameters"></span></p>
<h2 id="71-opening-file-descriptors-using-parameters"><a class="header" href="#71-opening-file-descriptors-using-parameters">7.1 Opening file descriptors using parameters</a></h2>
<p><span id="index-file-descriptors_002c-use-with-parameters"></span>
<span id="index-parameters_002c-for-using-file-descriptors"></span></p>
<p>When the shell is parsing arguments to a command, and the shell option
<code>IGNORE_BRACES</code> is not set, a different form of redirection is allowed:
instead of a digit before the operator there is a valid shell identifier
enclosed in braces. The shell will open a new file descriptor that is
guaranteed to be at least 10 and set the parameter named by the
identifier to the file descriptor opened. No whitespace is allowed
between the closing brace and the redirection character. For example:</p>
<blockquote>
<p>... <code>{myfd}&gt;&amp;1</code></p>
</blockquote>
<p>This opens a new file descriptor that is a duplicate of file descriptor
1 and sets the parameter <code>myfd</code> to the number of the file descriptor,
which will be at least 10. The new file descriptor can be written to
using the syntax <code>&gt;&amp;$myfd</code>. The file descriptor remains open in
subshells</p>
<p>The syntax <code>{``varid``}&gt;&amp;-</code>, for example <code>{myfd}&gt;&amp;-</code>, may be used to
close a file descriptor opened in this fashion. Note that the parameter
given by <code>varid</code> must previously be set to a file descriptor in this
case.</p>
<p>It is an error to open or close a file descriptor in this fashion when
the parameter is readonly. However, it is not an error to read or write
a file descriptor using <code>&lt;&amp;$``param</code> or <code>&gt;&amp;$``param</code> if <code>param</code> is
readonly.</p>
<p>If the option <code>CLOBBER</code> is unset, it is an error to open a file
descriptor using a parameter that is already set to an open file
descriptor previously allocated by this mechanism. Unsetting the
parameter before using it for allocating a file descriptor avoids the
error.</p>
<p>Note that this mechanism merely allocates or closes a file descriptor;
it does not perform any redirections from or to it. It is usually
convenient to allocate a file descriptor prior to use as an argument to
<code>exec</code>. The syntax does not in any case work when used around complex
commands such as parenthesised subshells or loops, where the opening
brace is interpreted as part of a command list to be executed in the
current shell.</p>
<p>The following shows a typical sequence of allocation, use, and closing
of a file descriptor:</p>
<div class="example">
<pre><code class="language-example">integer myfd
exec {myfd}&gt;~/logs/mylogfile.txt
print This is a log message. &gt;&amp;$myfd
exec {myfd}&gt;&amp;-
</code></pre>
</div>
<p>Note that the expansion of the variable in the expression <code>&gt;&amp;$myfd</code>
occurs at the point the redirection is opened. This is after the
expansion of command arguments and after any redirections to the left on
the command line have been processed.</p>
<hr />
<p><span id="Multios"></span></p>
<h2 id="72-multios"><a class="header" href="#72-multios">7.2 Multios</a></h2>
<p><span id="index-multios"></span>
<span id="index-MULTIOS_002c-use-of"></span></p>
<p>If the user tries to open a file descriptor for writing more than once,
the shell opens the file descriptor as a pipe to a process that copies
its input to all the specified outputs, similar to tee, provided the
<code>MULTIOS</code> option is set, as it is by default. Thus:</p>
<div class="example">
<pre><code class="language-example">date &gt;foo &gt;bar
</code></pre>
</div>
<p>writes the date to two files, named <code>foo</code> and <code>bar</code>. Note that a
pipe is an implicit redirection; thus</p>
<div class="example">
<pre><code class="language-example">date &gt;foo | cat
</code></pre>
</div>
<p>writes the date to the file <code>foo</code>, and also pipes it to cat.</p>
<p>Note that the shell opens all the files to be used in the multio process
immediately, not at the point they are about to be written.</p>
<p>Note also that redirections are always expanded in order. This happens
regardless of the setting of the <code>MULTIOS</code> option, but with the option
in effect there are additional consequences. For example, the meaning of
the expression <code>&gt;&amp;1</code> will change after a previous redirection:</p>
<div class="example">
<pre><code class="language-example">date &gt;&amp;1 &gt;output
</code></pre>
</div>
<p>In the case above, the <code>&gt;&amp;1</code> refers to the standard output at the start
of the line; the result is similar to the <code>tee</code> command. However,
consider:</p>
<div class="example">
<pre><code class="language-example">date &gt;output &gt;&amp;1
</code></pre>
</div>
<p>As redirections are evaluated in order, when the <code>&gt;&amp;1</code> is encountered
the standard output is set to the file <code>output</code> and another copy of the
output is therefore sent to that file. This is unlikely to be what is
intended.</p>
<p>If the <code>MULTIOS</code> option is set, the word after a redirection operator is
also subjected to filename generation (globbing). Thus</p>
<div class="example">
<pre><code class="language-example">: &gt; *
</code></pre>
</div>
<p>will truncate all files in the current directory, assuming theres at
least one. (Without the <code>MULTIOS</code> option, it would create an empty file
called <code>*</code>.) Similarly, you can do</p>
<div class="example">
<pre><code class="language-example">echo exit 0 &gt;&gt; *.sh
</code></pre>
</div>
<p>If the user tries to open a file descriptor for reading more than once,
the shell opens the file descriptor as a pipe to a process that copies
all the specified inputs to its output in the order specified, provided
the <code>MULTIOS</code> option is set. It should be noted that each file is opened
immediately, not at the point where it is about to be read: this
behaviour differs from <code>cat</code>, so if strictly standard behaviour is
needed, <code>cat</code> should be used instead.</p>
<p>Thus</p>
<div class="example">
<pre><code class="language-example">sort &lt;foo &lt;fubar
</code></pre>
</div>
<p>or even</p>
<div class="example">
<pre><code class="language-example">sort &lt;f{oo,ubar}
</code></pre>
</div>
<p>is equivalent to <code>cat foo fubar | sort</code>.</p>
<p>Expansion of the redirection argument occurs at the point the
redirection is opened, at the point described above for the expansion of
the variable in <code>&gt;&amp;$myfd</code>.</p>
<p>Note that a pipe is an implicit redirection; thus</p>
<div class="example">
<pre><code class="language-example">cat bar | sort &lt;foo
</code></pre>
</div>
<p>is equivalent to <code>cat bar foo | sort</code> (note the order of the inputs).</p>
<p>If the <code>MULTIOS</code> option is <em>un</em>set, each redirection replaces the
previous redirection for that file descriptor. However, all files
redirected to are actually opened, so</p>
<div class="example">
<pre><code class="language-example">echo Hello &gt; bar &gt; baz
</code></pre>
</div>
<p>when <code>MULTIOS</code> is unset will truncate <code>bar</code>, and write <code>Hello</code> into
<code>baz</code>.</p>
<p>There is a problem when an output multio is attached to an external
program. A simple example shows this:</p>
<div class="example">
<pre><code class="language-example">cat file &gt;file1 &gt;file2
cat file1 file2
</code></pre>
</div>
<p>Here, it is possible that the second <code>cat</code> will not display the full
contents of <code>file1</code> and <code>file2</code> (i.e. the original contents of <code>file</code>
repeated twice).</p>
<p>The reason for this is that the multios are spawned after the <code>cat</code>
process is forked from the parent shell, so the parent shell does not
wait for the multios to finish writing data. This means the command as
shown can exit before <code>file1</code> and <code>file2</code> are completely written. As a
workaround, it is possible to run the <code>cat</code> process as part of a job in
the current shell:</p>
<div class="example">
<pre><code class="language-example">{ cat file } &gt;file &gt;file2
</code></pre>
</div>
<p>Here, the <code>{``...``}</code> job will pause to wait for both files to be
written.</p>
<hr />
<p><span id="Redirections-with-no-command"></span></p>
<h2 id="73-redirections-with-no-command"><a class="header" href="#73-redirections-with-no-command">7.3 Redirections with no command</a></h2>
<p>When a simple command consists of one or more redirection operators and
zero or more parameter assignments, but no command name, zsh can behave
in several ways.</p>
<p><span id="index-NULLCMD_002c-use-of"></span>
<span id="index-CSH_005fNULLCMD_002c-use-of"></span></p>
<p>If the parameter <code>NULLCMD</code> is not set or the option <code>CSH_NULLCMD</code> is
set, an error is caused. This is the csh behavior and <code>CSH_NULLCMD</code> is
set by default when emulating csh.</p>
<p><span id="index-SH_005fNULLCMD_002c-use-of"></span></p>
<p>If the option <code>SH_NULLCMD</code> is set, the builtin <code>:</code> is inserted as a
command with the given redirections. This is the default when emulating
sh or ksh.</p>
<p><span id="index-READNULLCMD_002c-use-of"></span></p>
<p>Otherwise, if the parameter <code>NULLCMD</code> is set, its value will be used as
a command with the given redirections. If both <code>NULLCMD</code> and
<code>READNULLCMD</code> are set, then the value of the latter will be used instead
of that of the former when the redirection is an input. The default for
<code>NULLCMD</code> is <code>cat</code> and for <code>READNULLCMD</code> is <code>more</code>. Thus</p>
<div class="example">
<pre><code class="language-example">&lt; file
</code></pre>
</div>
<p>shows the contents of <code>file</code> on standard output, with paging if that is
a terminal. <code>NULLCMD</code> and <code>READNULLCMD</code> may refer to shell functions.</p>
<hr />
<p>This document was generated on <em>February 15, 2020</em> using
<a href="http://www.nongnu.org/texi2html/"><em>texi2html 5.0</em></a>.<br />
Zsh version 5.8, released on February 14, 2020.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="Shell-Grammar.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="Command-Execution.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="Shell-Grammar.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="Command-Execution.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>
<!-- Livereload script (if served using the cli tool) -->
<script type="text/javascript">
var socket = new WebSocket("ws://localhost:3000/__livereload");
socket.onmessage = function (event) {
if (event.data === "reload") {
socket.close();
location.reload();
}
};
window.onbeforeunload = function() {
socket.close();
}
</script>
<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>

471
book/Roadmap.html Normal file
View File

@ -0,0 +1,471 @@
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Roadmap - Zsh Manual</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 -->
</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 "><a href="The-Z-Shell-Manual.html"><strong aria-hidden="true">1.</strong> The Z Shell Manual</a></li><li class="chapter-item expanded "><a href="Introduction.html"><strong aria-hidden="true">2.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="Roadmap.html" class="active"><strong aria-hidden="true">3.</strong> Roadmap</a></li><li class="chapter-item expanded "><a href="Invocation.html"><strong aria-hidden="true">4.</strong> Invocation</a></li><li class="chapter-item expanded "><a href="Files.html"><strong aria-hidden="true">5.</strong> Files</a></li><li class="chapter-item expanded "><a href="Shell-Grammar.html"><strong aria-hidden="true">6.</strong> Shell Grammar</a></li><li class="chapter-item expanded "><a href="Redirection.html"><strong aria-hidden="true">7.</strong> Redirection</a></li><li class="chapter-item expanded "><a href="Command-Execution.html"><strong aria-hidden="true">8.</strong> Command Execution</a></li><li class="chapter-item expanded "><a href="Functions.html"><strong aria-hidden="true">9.</strong> Functions</a></li><li class="chapter-item expanded "><a href="Jobs-_0026-Signals.html"><strong aria-hidden="true">10.</strong> Jobs &amp; Signals</a></li><li class="chapter-item expanded "><a href="Arithmetic-Evaluation.html"><strong aria-hidden="true">11.</strong> Arithmetic Evaluation</a></li><li class="chapter-item expanded "><a href="Conditional-Expressions.html"><strong aria-hidden="true">12.</strong> Conditional Expressions</a></li><li class="chapter-item expanded "><a href="Prompt-Expansion.html"><strong aria-hidden="true">13.</strong> Prompt Expansion</a></li><li class="chapter-item expanded "><a href="Expansion.html"><strong aria-hidden="true">14.</strong> Expansion</a></li><li class="chapter-item expanded "><a href="Parameters.html"><strong aria-hidden="true">15.</strong> Parameters</a></li><li class="chapter-item expanded "><a href="Options.html"><strong aria-hidden="true">16.</strong> Options</a></li><li class="chapter-item expanded "><a href="Shell-Builtin-Commands.html"><strong aria-hidden="true">17.</strong> Shell Builtin Commands</a></li><li class="chapter-item expanded "><a href="Zsh-Line-Editor.html"><strong aria-hidden="true">18.</strong> Zsh Line Editor</a></li><li class="chapter-item expanded "><a href="Completion-Widgets.html"><strong aria-hidden="true">19.</strong> Completion Widgets</a></li><li class="chapter-item expanded "><a href="Completion-System.html"><strong aria-hidden="true">20.</strong> Completion System</a></li><li class="chapter-item expanded "><a href="Completion-Using-compctl.html"><strong aria-hidden="true">21.</strong> Completion Using compctl</a></li><li class="chapter-item expanded "><a href="Zsh-Modules.html"><strong aria-hidden="true">22.</strong> Zsh Modules</a></li><li class="chapter-item expanded "><a href="Calendar-Function-System.html"><strong aria-hidden="true">23.</strong> Calendar Function System</a></li><li class="chapter-item expanded "><a href="TCP-Function-System.html"><strong aria-hidden="true">24.</strong> TCP Function System</a></li><li class="chapter-item expanded "><a href="Zftp-Function-System.html"><strong aria-hidden="true">25.</strong> Zftp Function System</a></li><li class="chapter-item expanded "><a href="User-Contributions.html"><strong aria-hidden="true">26.</strong> User Contributions</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>
</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 Manual</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" name="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="#3-roadmap">3 Roadmap</a>
<ul>
<li><a href="#31-when-the-shell-starts">3.1 When the shell starts</a></li>
<li><a href="#32-interactive-use">3.2 Interactive Use</a>
<ul>
<li><a href="#321-completion">3.2.1 Completion</a></li>
<li><a href="#322-extending-the-line-editor">3.2.2 Extending the line editor</a></li>
</ul>
</li>
<li><a href="#33-options">3.3 Options</a></li>
<li><a href="#34-pattern-matching">3.4 Pattern Matching</a></li>
<li><a href="#35-general-comments-on-syntax">3.5 General Comments on Syntax</a></li>
<li><a href="#36-programming">3.6 Programming</a></li>
</ul>
</li>
</ul>
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<p><span id="Roadmap"></span> <span id="Roadmap-1"></span></p>
<h1 id="3-roadmap"><a class="header" href="#3-roadmap">3 Roadmap</a></h1>
<p><span id="index-roadmap"></span></p>
<p>The Zsh Manual, like the shell itself, is large and often complicated.
This section of the manual provides some pointers to areas of the shell
that are likely to be of particular interest to new users, and indicates
where in the rest of the manual the documentation is to be found.</p>
<hr />
<p><span id="When-the-shell-starts"></span></p>
<h2 id="31-when-the-shell-starts"><a class="header" href="#31-when-the-shell-starts">3.1 When the shell starts</a></h2>
<p>When it starts, the shell reads commands from various files. These can
be created or edited to customize the shell. See
<a href="Files.html#Files">Files</a>.</p>
<p>If no personal initialization files exist for the current user, a
function is run to help you change some of the most common settings. It
wont appear if your administrator has disabled the <code>zsh/newuser</code>
module. The function is designed to be self-explanatory. You can run it
by hand with <code>autoload -Uz zsh-newuser-install; zsh-newuser-install -f</code>. See also <a href="User-Contributions.html#User-Configuration-Functions">User Configuration
Functions</a>.</p>
<hr />
<p><span id="Interactive-Use"></span></p>
<h2 id="32-interactive-use"><a class="header" href="#32-interactive-use">3.2 Interactive Use</a></h2>
<p>Interaction with the shell uses the builtin Zsh Line Editor, ZLE. This
is described in detail in <a href="Zsh-Line-Editor.html#Zsh-Line-Editor">Zsh Line
Editor</a>.</p>
<p>The first decision a user must make is whether to use the Emacs or Vi
editing mode as the keys for editing are substantially different. Emacs
editing mode is probably more natural for beginners and can be selected
explicitly with the command <code>bindkey -e</code>.</p>
<p>A history mechanism for retrieving previously typed lines (most simply
with the Up or Down arrow keys) is available; note that, unlike other
shells, zsh will not save these lines when the shell exits unless you
set appropriate variables, and the number of history lines retained by
default is quite small (30 lines). See the description of the shell
variables (referred to in the documentation as parameters) <code>HISTFILE</code>,
<code>HISTSIZE</code> and <code>SAVEHIST</code> in <a href="Parameters.html#Parameters-Used-By-The-Shell">Parameters Used By The
Shell</a>. Note that its
currently only possible to read and write files saving history when the
shell is interactive, i.e. it does not work from scripts.</p>
<p>The shell now supports the UTF-8 character set (and also others if
supported by the operating system). This is (mostly) handled
transparently by the shell, but the degree of support in terminal
emulators is variable. There is some discussion of this in the shell
FAQ, <code>http://www.zsh.org/FAQ/</code>. Note in particular that for combining
characters to be handled the option <code>COMBINING_CHARS</code> needs to be set.
Because the shell is now more sensitive to the definition of the
character set, note that if you are upgrading from an older version of
the shell you should ensure that the appropriate variable, either <code>LANG</code>
(to affect all aspects of the shells operation) or <code>LC_CTYPE</code> (to
affect only the handling of character sets) is set to an appropriate
value. This is true even if you are using a single-byte character set
including extensions of ASCII such as <code>ISO-8859-1</code> or <code>ISO-8859-15</code>. See
the description of <code>LC_CTYPE</code> in
<a href="Parameters.html#Parameters">Parameters</a>.</p>
<hr />
<p><span id="Completion-1"></span></p>
<h3 id="321-completion"><a class="header" href="#321-completion">3.2.1 Completion</a></h3>
<p>Completion is a feature present in many shells. It allows the user to
type only a part (usually the prefix) of a word and have the shell fill
in the rest. The completion system in zsh is programmable. For example,
the shell can be set to complete email addresses in arguments to the
mail command from your <code>~/.abook/addressbook</code>; usernames, hostnames, and
even remote paths in arguments to scp, and so on. Anything that can be
written in or glued together with zsh can be the source of what the line
editor offers as possible completions.</p>
<p>Zsh has two completion systems, an old, so called <code>compctl</code> completion
(named after the builtin command that serves as its complete and only
user interface), and a new one, referred to as <code>compsys</code>, organized as
library of builtin and user-defined functions. The two systems differ in
their interface for specifying the completion behavior. The new system
is more customizable and is supplied with completions for many commonly
used commands; it is therefore to be preferred.</p>
<p>The completion system must be enabled explicitly when the shell starts.
For more information see <a href="Completion-System.html#Completion-System">Completion
System</a>.</p>
<hr />
<p><span id="Extending-the-line-editor"></span></p>
<h3 id="322-extending-the-line-editor"><a class="header" href="#322-extending-the-line-editor">3.2.2 Extending the line editor</a></h3>
<p>Apart from completion, the line editor is highly extensible by means of
shell functions. Some useful functions are provided with the shell; they
provide facilities such as:</p>
<ul>
<li>
<p><code>insert-composed-char</code><br />
composing characters not found on the keyboard</p>
</li>
<li>
<p><code>match-words-by-style</code><br />
configuring what the line editor considers a word when moving or
deleting by word</p>
</li>
<li>
<p><code>history-beginning-search-backward-end</code>, etc.<br />
alternative ways of searching the shell history</p>
</li>
<li>
<p><code>replace-string</code>, <code>replace-pattern</code><br />
functions for replacing strings or patterns globally in the command
line</p>
</li>
<li>
<p><code>edit-command-line</code><br />
edit the command line with an external editor.</p>
</li>
</ul>
<p>See <a href="User-Contributions.html#ZLE-Functions">ZLE Functions</a> for
descriptions of these.</p>
<hr />
<p><span id="Options-3"></span></p>
<h2 id="33-options"><a class="header" href="#33-options">3.3 Options</a></h2>
<p>The shell has a large number of options for changing its behaviour.
These cover all aspects of the shell; browsing the full documentation is
the only good way to become acquainted with the many possibilities. See
<a href="Options.html#Options">Options</a>.</p>
<hr />
<p><span id="Pattern-Matching"></span></p>
<h2 id="34-pattern-matching"><a class="header" href="#34-pattern-matching">3.4 Pattern Matching</a></h2>
<p>The shell has a rich set of patterns which are available for file
matching (described in the documentation as filename generation and
also known for historical reasons as globbing) and for use when
programming. These are described in <a href="Expansion.html#Filename-Generation">Filename
Generation</a>.</p>
<p>Of particular interest are the following patterns that are not commonly
supported by other systems of pattern matching:</p>
<ul>
<li>
<p><code>**</code><br />
for matching over multiple directories</p>
</li>
<li>
<p><code>|</code><br />
for matching either of two alternatives</p>
</li>
<li>
<p><code>~</code>, <code>^</code><br />
the ability to exclude patterns from matching when the
<code>EXTENDED_GLOB</code> option is set</p>
</li>
<li>
<p><code>(``...``)</code><br />
glob qualifiers, included in parentheses at the end of the pattern,
which select files by type (such as directories) or attribute (such
as size).</p>
</li>
</ul>
<hr />
<p><span id="General-Comments-on-Syntax"></span></p>
<h2 id="35-general-comments-on-syntax"><a class="header" href="#35-general-comments-on-syntax">3.5 General Comments on Syntax</a></h2>
<p>Although the syntax of zsh is in ways similar to the Korn shell, and
therefore more remotely to the original UNIX shell, the Bourne shell,
its default behaviour does not entirely correspond to those shells.
General shell syntax is introduced in <a href="Shell-Grammar.html#Shell-Grammar">Shell
Grammar</a>.</p>
<p>One commonly encountered difference is that variables substituted onto
the command line are not split into words. See the description of the
shell option <code>SH_WORD_SPLIT</code> in <a href="Expansion.html#Parameter-Expansion">Parameter
Expansion</a>. In zsh, you can either
explicitly request the splitting (e.g. <code>${=foo}</code>) or use an array when
you want a variable to expand to more than one word. See <a href="Parameters.html#Array-Parameters">Array
Parameters</a>.</p>
<hr />
<p><span id="Programming"></span></p>
<h2 id="36-programming"><a class="header" href="#36-programming">3.6 Programming</a></h2>
<p>The most convenient way of adding enhancements to the shell is typically
by writing a shell function and arranging for it to be autoloaded.
Functions are described in <a href="Functions.html#Functions">Functions</a>. Users
changing from the C shell and its relatives should notice that aliases
are less used in zsh as they dont perform argument substitution, only
simple text replacement.</p>
<p>A few general functions, other than those for the line editor described
above, are provided with the shell and are described in <a href="User-Contributions.html#User-Contributions">User
Contributions</a>. Features
include:</p>
<ul>
<li>
<p><code>promptinit</code><br />
a prompt theme system for changing prompts easily, see <a href="User-Contributions.html#Prompt-Themes">Prompt
Themes</a></p>
</li>
<li>
<p><code>zsh-mime-setup</code><br />
a MIME-handling system which dispatches commands according to the
suffix of a file as done by graphical file managers</p>
</li>
<li>
<p><code>zcalc</code><br />
a calculator</p>
</li>
<li>
<p><code>zargs</code><br />
a version of <code>xargs</code> that makes the <code>find</code> command redundant</p>
</li>
<li>
<p><code>zmv</code><br />
a command for renaming files by means of shell patterns.</p>
</li>
</ul>
<hr />
<p>This document was generated on <em>February 15, 2020</em> using
<a href="http://www.nongnu.org/texi2html/"><em>texi2html 5.0</em></a>.<br />
Zsh version 5.8, released on February 14, 2020.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="Introduction.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="Invocation.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="Introduction.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="Invocation.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>
<!-- Livereload script (if served using the cli tool) -->
<script type="text/javascript">
var socket = new WebSocket("ws://localhost:3000/__livereload");
socket.onmessage = function (event) {
if (event.data === "reload") {
socket.close();
location.reload();
}
};
window.onbeforeunload = function() {
socket.close();
}
</script>
<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>

File diff suppressed because it is too large Load Diff

871
book/Shell-Grammar.html Normal file
View File

@ -0,0 +1,871 @@
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Shell Grammar - Zsh Manual</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 -->
</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 "><a href="The-Z-Shell-Manual.html"><strong aria-hidden="true">1.</strong> The Z Shell Manual</a></li><li class="chapter-item expanded "><a href="Introduction.html"><strong aria-hidden="true">2.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="Roadmap.html"><strong aria-hidden="true">3.</strong> Roadmap</a></li><li class="chapter-item expanded "><a href="Invocation.html"><strong aria-hidden="true">4.</strong> Invocation</a></li><li class="chapter-item expanded "><a href="Files.html"><strong aria-hidden="true">5.</strong> Files</a></li><li class="chapter-item expanded "><a href="Shell-Grammar.html" class="active"><strong aria-hidden="true">6.</strong> Shell Grammar</a></li><li class="chapter-item expanded "><a href="Redirection.html"><strong aria-hidden="true">7.</strong> Redirection</a></li><li class="chapter-item expanded "><a href="Command-Execution.html"><strong aria-hidden="true">8.</strong> Command Execution</a></li><li class="chapter-item expanded "><a href="Functions.html"><strong aria-hidden="true">9.</strong> Functions</a></li><li class="chapter-item expanded "><a href="Jobs-_0026-Signals.html"><strong aria-hidden="true">10.</strong> Jobs &amp; Signals</a></li><li class="chapter-item expanded "><a href="Arithmetic-Evaluation.html"><strong aria-hidden="true">11.</strong> Arithmetic Evaluation</a></li><li class="chapter-item expanded "><a href="Conditional-Expressions.html"><strong aria-hidden="true">12.</strong> Conditional Expressions</a></li><li class="chapter-item expanded "><a href="Prompt-Expansion.html"><strong aria-hidden="true">13.</strong> Prompt Expansion</a></li><li class="chapter-item expanded "><a href="Expansion.html"><strong aria-hidden="true">14.</strong> Expansion</a></li><li class="chapter-item expanded "><a href="Parameters.html"><strong aria-hidden="true">15.</strong> Parameters</a></li><li class="chapter-item expanded "><a href="Options.html"><strong aria-hidden="true">16.</strong> Options</a></li><li class="chapter-item expanded "><a href="Shell-Builtin-Commands.html"><strong aria-hidden="true">17.</strong> Shell Builtin Commands</a></li><li class="chapter-item expanded "><a href="Zsh-Line-Editor.html"><strong aria-hidden="true">18.</strong> Zsh Line Editor</a></li><li class="chapter-item expanded "><a href="Completion-Widgets.html"><strong aria-hidden="true">19.</strong> Completion Widgets</a></li><li class="chapter-item expanded "><a href="Completion-System.html"><strong aria-hidden="true">20.</strong> Completion System</a></li><li class="chapter-item expanded "><a href="Completion-Using-compctl.html"><strong aria-hidden="true">21.</strong> Completion Using compctl</a></li><li class="chapter-item expanded "><a href="Zsh-Modules.html"><strong aria-hidden="true">22.</strong> Zsh Modules</a></li><li class="chapter-item expanded "><a href="Calendar-Function-System.html"><strong aria-hidden="true">23.</strong> Calendar Function System</a></li><li class="chapter-item expanded "><a href="TCP-Function-System.html"><strong aria-hidden="true">24.</strong> TCP Function System</a></li><li class="chapter-item expanded "><a href="Zftp-Function-System.html"><strong aria-hidden="true">25.</strong> Zftp Function System</a></li><li class="chapter-item expanded "><a href="User-Contributions.html"><strong aria-hidden="true">26.</strong> User Contributions</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>
</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 Manual</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" name="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="#6-shell-grammar">6 Shell Grammar</a>
<ul>
<li><a href="#61-simple-commands--pipelines">6.1 Simple Commands &amp; Pipelines</a></li>
<li><a href="#62-precommand-modifiers">6.2 Precommand Modifiers</a></li>
<li><a href="#63-complex-commands">6.3 Complex Commands</a></li>
<li><a href="#64-alternate-forms-for-complex-commands">6.4 Alternate Forms For Complex Commands</a></li>
<li><a href="#65-reserved-words">6.5 Reserved Words</a></li>
<li><a href="#66-errors">6.6 Errors</a></li>
<li><a href="#67-comments">6.7 Comments</a></li>
<li><a href="#68-aliasing">6.8 Aliasing</a>
<ul>
<li><a href="#681-alias-difficulties">6.8.1 Alias difficulties</a></li>
</ul>
</li>
<li><a href="#69-quoting">6.9 Quoting</a></li>
</ul>
</li>
</ul>
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<p><span id="Shell-Grammar"></span> <span id="Shell-Grammar-1"></span></p>
<h1 id="6-shell-grammar"><a class="header" href="#6-shell-grammar">6 Shell Grammar</a></h1>
<p><span id="index-shell-grammar"></span>
<span id="index-grammar_002c-shell"></span></p>
<hr />
<p><span id="Simple-Commands-_0026-Pipelines"></span>
<span id="Simple-Commands-_0026-Pipelines-1"></span></p>
<h2 id="61-simple-commands--pipelines"><a class="header" href="#61-simple-commands--pipelines">6.1 Simple Commands &amp; Pipelines</a></h2>
<p><span id="index-simple-commands"></span>
<span id="index-commands_002c-simple"></span></p>
<p>A <em>simple command</em> is a sequence of optional parameter assignments
followed by blank-separated words, with optional redirections
interspersed. For a description of assignment, see the beginning of
<a href="Parameters.html#Parameters">Parameters</a>.</p>
<p>The first word is the command to be executed, and the remaining words,
if any, are arguments to the command. If a command name is given, the
parameter assignments modify the environment of the command when it is
executed. The value of a simple command is its exit status, or 128 plus
the signal number if terminated by a signal. For example,</p>
<div class="example">
<pre><code class="language-example">echo foo
</code></pre>
</div>
<p>is a simple command with arguments.</p>
<p><span id="index-pipeline"></span></p>
<p>A <em>pipeline</em> is either a simple command, or a sequence of two or more
simple commands where each command is separated from the next by <code>|</code>
or <code>|&amp;</code>. Where commands are separated by <code>|</code>, the standard output of
the first command is connected to the standard input of the next. <code>|&amp;</code>
is shorthand for <code>2&gt;&amp;1 |</code>, which connects both the standard output and
the standard error of the command to the standard input of the next. The
value of a pipeline is the value of the last command, unless the
pipeline is preceded by <code>!</code> in which case the value is the logical
inverse of the value of the last command. For example,</p>
<div class="example">
<pre><code class="language-example">echo foo | sed 's/foo/bar/'
</code></pre>
</div>
<p>is a pipeline, where the output (<code>foo</code> plus a newline) of the first
command will be passed to the input of the second.</p>
<p><span id="index-coproc"></span> <span id="index-coprocess"></span></p>
<p>If a pipeline is preceded by <code>coproc</code>, it is executed as a coprocess;
a two-way pipe is established between it and the parent shell. The shell
can read from or write to the coprocess by means of the <code>&gt;&amp;p</code> and
<code>&lt;&amp;p</code> redirection operators or with <code>print -p</code> and <code>read -p</code>. A
pipeline cannot be preceded by both <code>coproc</code> and <code>!</code>. If job control
is active, the coprocess can be treated in other than input and output
as an ordinary background job.</p>
<p><span id="index-sublist"></span></p>
<p>A <em>sublist</em> is either a single pipeline, or a sequence of two or more
pipelines separated by <code>&amp;&amp;</code> or <code>||</code>. If two pipelines are separated
by <code>&amp;&amp;</code>, the second pipeline is executed only if the first succeeds
(returns a zero status). If two pipelines are separated by <code>||</code>, the
second is executed only if the first fails (returns a nonzero status).
Both operators have equal precedence and are left associative. The value
of the sublist is the value of the last pipeline executed. For example,</p>
<div class="example">
<pre><code class="language-example">dmesg | grep panic &amp;&amp; print yes
</code></pre>
</div>
<p>is a sublist consisting of two pipelines, the second just a simple
command which will be executed if and only if the <code>grep</code> command returns
a zero status. If it does not, the value of the sublist is that return
status, else it is the status returned by the <code>print</code> (almost certainly
zero).</p>
<p><span id="index-list"></span></p>
<p>A <em>list</em> is a sequence of zero or more sublists, in which each sublist
is terminated by <code>;</code>, <code>&amp;</code>, <code>&amp;|</code>, <code>&amp;!</code>, or a newline. This
terminator may optionally be omitted from the last sublist in the list
when the list appears as a complex command inside <code>(</code>...<code>)</code> or
<code>{</code>...<code>}</code>. When a sublist is terminated by <code>;</code> or newline, the
shell waits for it to finish before executing the next sublist. If a
sublist is terminated by a <code>&amp;</code>, <code>&amp;|</code>, or <code>&amp;!</code>, the shell executes
the last pipeline in it in the background, and does not wait for it to
finish (note the difference from other shells which execute the whole
sublist in the background). A backgrounded pipeline returns a status of
zero.</p>
<p>More generally, a list can be seen as a set of any shell commands
whatsoever, including the complex commands below; this is implied
wherever the word list appears in later descriptions. For example, the
commands in a shell function form a special sort of list.</p>
<hr />
<p><span id="Precommand-Modifiers"></span>
<span id="Precommand-Modifiers-1"></span></p>
<h2 id="62-precommand-modifiers"><a class="header" href="#62-precommand-modifiers">6.2 Precommand Modifiers</a></h2>
<p><span id="index-precommand-modifiers"></span>
<span id="index-modifiers_002c-precommand"></span></p>
<p>A simple command may be preceded by a <em>precommand modifier</em>, which will
alter how the command is interpreted. These modifiers are shell builtin
commands with the exception of <code>nocorrect</code> which is a reserved word.</p>
<p><span id="index-_002d"></span></p>
<p><code>-</code></p>
<p>The command is executed with a <code>-</code> prepended to its <code>argv[0]</code> string.</p>
<p><span id="index-builtin"></span></p>
<p><code>builtin</code></p>
<p>The command word is taken to be the name of a builtin command, rather
than a shell function or external command.</p>
<p><span id="index-command"></span></p>
<p><code>command</code> [ <code>-pvV</code> ]</p>
<p>The command word is taken to be the name of an external command, rather
than a shell function or builtin. If the <code>POSIX_BUILTINS</code> option is set,
builtins will also be executed but certain special properties of them
are suppressed. The <code>-p</code> flag causes a default path to be searched
instead of that in <code>$path</code>. With the <code>-v</code> flag, <code>command</code> is similar to
<code>whence</code> and with <code>-V</code>, it is equivalent to <code>whence -v</code>.</p>
<p><span id="index-exec"></span></p>
<p><code>exec</code> [ <code>-cl</code> ] [ <code>-a</code> <code>argv0</code> ]</p>
<p>The following command together with any arguments is run in place of the
current process, rather than as a sub-process. The shell does not fork
and is replaced. The shell does not invoke <code>TRAPEXIT</code>, nor does it
source <code>zlogout</code> files. The options are provided for compatibility with
other shells.</p>
<p>The <code>-c</code> option clears the environment.</p>
<p>The <code>-l</code> option is equivalent to the <code>-</code> precommand modifier, to treat
the replacement command as a login shell; the command is executed with a
<code>-</code> prepended to its <code>argv[0]</code> string. This flag has no effect if used
together with the <code>-a</code> option.</p>
<p>The <code>-a</code> option is used to specify explicitly the <code>argv[0]</code> string (the
name of the command as seen by the process itself) to be used by the
replacement command and is directly equivalent to setting a value for
the <code>ARGV0</code> environment variable.</p>
<p><span id="index-nocorrect"></span></p>
<p><code>nocorrect</code></p>
<p>Spelling correction is not done on any of the words. This must appear
before any other precommand modifier, as it is interpreted immediately,
before any parsing is done. It has no effect in non-interactive shells.</p>
<p><span id="index-noglob"></span></p>
<p><code>noglob</code></p>
<p>Filename generation (globbing) is not performed on any of the words.</p>
<hr />
<p><span id="Complex-Commands"></span>
<span id="Complex-Commands-1"></span></p>
<h2 id="63-complex-commands"><a class="header" href="#63-complex-commands">6.3 Complex Commands</a></h2>
<p><span id="index-complex-commands"></span>
<span id="index-commands_002c-complex"></span></p>
<p>A <em>complex command</em> in zsh is one of the following:</p>
<p><span id="index-if"></span> <span id="index-if-construct"></span></p>
<p><code>if</code> <code>list</code> <code>then</code> <code>list</code> [ <code>elif</code> <code>list</code> <code>then</code> <code>list</code> ] ... [
<code>else</code> <code>list</code> ] <code>fi</code></p>
<p>The <code>if</code> <code>list</code> is executed, and if it returns a zero exit status, the
<code>then</code> <code>list</code> is executed. Otherwise, the <code>elif</code> <code>list</code> is executed and
if its status is zero, the <code>then</code> <code>list</code> is executed. If each <code>elif</code>
<code>list</code> returns nonzero status, the <code>else</code> <code>list</code> is executed.</p>
<p><span id="index-for"></span> <span id="index-for-loops"></span>
<span id="index-loops_002c-for"></span></p>
<p><code>for</code> <code>name</code> ... [ <code>in</code> <code>word</code> ... ] <code>term</code> <code>do</code> <code>list</code> <code>done</code></p>
<p>Expand the list of <code>word</code>s, and set the parameter <code>name</code> to each of them
in turn, executing <code>list</code> each time. If the <code>in</code> <code>word</code> is omitted,
use the positional parameters instead of the <code>word</code>s.</p>
<p>The <code>term</code> consists of one or more newline or <code>;</code> which terminate the
<code>word</code>s, and are optional when the <code>in</code> <code>word</code> is omitted.</p>
<p>More than one parameter <code>name</code> can appear before the list of <code>word</code>s. If
<code>N</code> <code>name</code>s are given, then on each execution of the loop the next <code>N</code>
<code>word</code>s are assigned to the corresponding parameters. If there are more
<code>name</code>s than remaining <code>word</code>s, the remaining parameters are each set to
the empty string. Execution of the loop ends when there is no remaining
<code>word</code> to assign to the first <code>name</code>. It is only possible for <code>in</code> to
appear as the first <code>name</code> in the list, else it will be treated as
marking the end of the list.</p>
<p><code>for ((</code> [<code>expr1</code>] <code>;</code> [<code>expr2</code>] <code>;</code> [<code>expr3</code>] <code>)) do</code> <code>list</code>
<code>done</code></p>
<p>The arithmetic expression <code>expr1</code> is evaluated first (see <a href="Arithmetic-Evaluation.html#Arithmetic-Evaluation">Arithmetic
Evaluation</a>). The
arithmetic expression <code>expr2</code> is repeatedly evaluated until it evaluates
to zero and when non-zero, <code>list</code> is executed and the arithmetic
expression <code>expr3</code> evaluated. If any expression is omitted, then it
behaves as if it evaluated to 1.</p>
<p><span id="index-while"></span> <span id="index-while-loops"></span>
<span id="index-loops_002c-while"></span></p>
<p><code>while</code> <code>list</code> <code>do</code> <code>list</code> <code>done</code></p>
<p>Execute the <code>do</code> <code>list</code> as long as the <code>while</code> <code>list</code> returns a zero
exit status.</p>
<p><span id="index-until"></span> <span id="index-until-loops"></span>
<span id="index-loops_002c-until"></span></p>
<p><code>until</code> <code>list</code> <code>do</code> <code>list</code> <code>done</code></p>
<p>Execute the <code>do</code> <code>list</code> as long as <code>until</code> <code>list</code> returns a nonzero exit
status.</p>
<p><span id="index-repeat"></span> <span id="index-repeat-loops"></span>
<span id="index-loops_002c-repeat"></span></p>
<p><code>repeat</code> <code>word</code> <code>do</code> <code>list</code> <code>done</code></p>
<p><code>word</code> is expanded and treated as an arithmetic expression, which must
evaluate to a number <code>n</code>. <code>list</code> is then executed <code>n</code> times.</p>
<p>The <code>repeat</code> syntax is disabled by default when the shell starts in a
mode emulating another shell. It can be enabled with the command
<code>enable -r repeat</code></p>
<p><span id="index-case"></span> <span id="index-case-selection"></span>
<span id="index-selection_002c-case"></span></p>
<p><code>case</code> <code>word</code> <code>in</code> [ [<code>(</code>] <code>pattern</code> [ <code>|</code> <code>pattern</code> ] ... <code>)</code>
<code>list</code> (<code>;;</code>|<code>;&amp;</code>|<code>;|</code>) ] ... <code>esac</code></p>
<p>Execute the <code>list</code> associated with the first <code>pattern</code> that matches
<code>word</code>, if any. The form of the patterns is the same as that used for
filename generation. See <a href="Expansion.html#Filename-Generation">Filename
Generation</a>.</p>
<p>Note further that, unless the <code>SH_GLOB</code> option is set, the whole pattern
with alternatives is treated by the shell as equivalent to a group of
patterns within parentheses, although white space may appear about the
parentheses and the vertical bar and will be stripped from the pattern
at those points. White space may appear elsewhere in the pattern; this
is not stripped. If the <code>SH_GLOB</code> option is set, so that an opening
parenthesis can be unambiguously treated as part of the case syntax, the
expression is parsed into separate words and these are treated as strict
alternatives (as in other shells).</p>
<p>If the <code>list</code> that is executed is terminated with <code>;&amp;</code> rather than <code>;;</code>,
the following list is also executed. The rule for the terminator of the
following list <code>;;</code>, <code>;&amp;</code> or <code>;|</code> is applied unless the <code>esac</code> is
reached.</p>
<p>If the <code>list</code> that is executed is terminated with <code>;|</code> the shell
continues to scan the <code>pattern</code>s looking for the next match, executing
the corresponding <code>list</code>, and applying the rule for the corresponding
terminator <code>;;</code>, <code>;&amp;</code> or <code>;|</code>. Note that <code>word</code> is not re-expanded; all
applicable <code>pattern</code>s are tested with the same <code>word</code>.</p>
<p><span id="index-select"></span> <span id="index-user-selection"></span>
<span id="index-selection_002c-user"></span></p>
<p><code>select</code> <code>name</code> [ <code>in</code> <code>word</code> ... <code>term</code> ] <code>do</code> <code>list</code> <code>done</code></p>
<p>where <code>term</code> is one or more newline or <code>;</code> to terminate the <code>word</code>s.
<span id="index-REPLY_002c-use-of"></span> Print the set of <code>word</code>s,
each preceded by a number. If the <code>in</code> <code>word</code> is omitted, use the
positional parameters. The <code>PROMPT3</code> prompt is printed and a line is
read from the line editor if the shell is interactive and that is
active, or else standard input. If this line consists of the number of
one of the listed <code>word</code>s, then the parameter <code>name</code> is set to the
<code>word</code> corresponding to this number. If this line is empty, the
selection list is printed again. Otherwise, the value of the parameter
<code>name</code> is set to null. The contents of the line read from standard input
is saved in the parameter <code>REPLY</code>. <code>list</code> is executed for each selection
until a break or end-of-file is encountered.</p>
<p><span id="index-subshell"></span></p>
<p><code>(</code> <code>list</code> <code>)</code></p>
<p>Execute <code>list</code> in a subshell. Traps set by the <code>trap</code> builtin are reset
to their default values while executing <code>list</code>.</p>
<p><code>{</code> <code>list</code> <code>}</code></p>
<p>Execute <code>list</code>.</p>
<p><span id="index-always"></span> <span id="index-always-blocks"></span>
<span id="index-try-blocks"></span></p>
<p><code>{</code> <code>try-list</code> <code>} always {</code> <code>always-list</code> <code>}</code></p>
<p>First execute <code>try-list</code>. Regardless of errors, or <code>break</code> or <code>continue</code>
commands encountered within <code>try-list</code>, execute <code>always-list</code>. Execution
then continues from the result of the execution of <code>try-list</code>; in other
words, any error, or <code>break</code> or <code>continue</code> command is treated in the
normal way, as if <code>always-list</code> were not present. The two chunks of code
are referred to as the try block and the always block.</p>
<p>Optional newlines or semicolons may appear after the <code>always</code>; note,
however, that they may <em>not</em> appear between the preceding closing brace
and the <code>always</code>.</p>
<p>An error in this context is a condition such as a syntax error which
causes the shell to abort execution of the current function, script, or
list. Syntax errors encountered while the shell is parsing the code do
not cause the <code>always-list</code> to be executed. For example, an erroneously
constructed <code>if</code> block in <code>try-list</code> would cause the shell to abort
during parsing, so that <code>always-list</code> would not be executed, while an
erroneous substitution such as <code>${*foo*}</code> would cause a run-time error,
after which <code>always-list</code> would be executed.</p>
<p>An error condition can be tested and reset with the special integer
variable <code>TRY_BLOCK_ERROR</code>. Outside an <code>always-list</code> the value is
irrelevant, but it is initialised to <code>-1</code>. Inside <code>always-list</code>, the
value is 1 if an error occurred in the <code>try-list</code>, else 0. If
<code>TRY_BLOCK_ERROR</code> is set to 0 during the <code>always-list</code>, the error
condition caused by the <code>try-list</code> is reset, and shell execution
continues normally after the end of <code>always-list</code>. Altering the value
during the <code>try-list</code> is not useful (unless this forms part of an
enclosing <code>always</code> block).</p>
<p>Regardless of <code>TRY_BLOCK_ERROR</code>, after the end of <code>always-list</code> the
normal shell status <code>$?</code> is the value returned from <code>try-list</code>. This
will be non-zero if there was an error, even if <code>TRY_BLOCK_ERROR</code> was
set to zero.</p>
<p>The following executes the given code, ignoring any errors it causes.
This is an alternative to the usual convention of protecting code by
executing it in a subshell.</p>
<div class="example">
<pre><code class="language-example">{
# code which may cause an error
} always {
# This code is executed regardless of the error.
(( TRY_BLOCK_ERROR = 0 ))
}
# The error condition has been reset.
</code></pre>
</div>
<p>When a <code>try</code> block occurs outside of any function, a <code>return</code> or a
<code>exit</code> encountered in <code>try-list</code> does <em>not</em> cause the execution of
<code>always-list</code>. Instead, the shell exits immediately after any <code>EXIT</code>
trap has been executed. Otherwise, a <code>return</code> command encountered in
<code>try-list</code> will cause the execution of <code>always-list</code>, just like <code>break</code>
and <code>continue</code>.</p>
<p><span id="index-function"></span></p>
<p><code>function</code> <code>word</code> ... [ <code>()</code> ] [ <code>term</code> ] <code>{</code> <code>list</code> <code>}</code></p>
<p><code>word</code> ... <code>()</code> [ <code>term</code> ] <code>{</code> <code>list</code> <code>}</code></p>
<p><code>word</code> ... <code>()</code> [ <code>term</code> ] <code>command</code></p>
<p>where <code>term</code> is one or more newline or <code>;</code>. Define a function which is
referenced by any one of <code>word</code>. Normally, only one <code>word</code> is provided;
multiple <code>word</code>s are usually only useful for setting traps. The body of
the function is the <code>list</code> between the <code>{</code> and <code>}</code>. See
<a href="Functions.html#Functions">Functions</a>.</p>
<p>If the option <code>SH_GLOB</code> is set for compatibility with other shells, then
whitespace may appear between the left and right parentheses when there
is a single <code>word</code>; otherwise, the parentheses will be treated as
forming a globbing pattern in that case.</p>
<p>In any of the forms above, a redirection may appear outside the function
body, for example</p>
<div class="example">
<pre><code class="language-example">func() { ... } 2&gt;&amp;1
</code></pre>
</div>
<p>The redirection is stored with the function and applied whenever the
function is executed. Any variables in the redirection are expanded at
the point the function is executed, but outside the function scope.</p>
<p><span id="index-timing"></span> <span id="index-time"></span></p>
<p><code>time</code> [ <code>pipeline</code> ]</p>
<p>The <code>pipeline</code> is executed, and timing statistics are reported on the
standard error in the form specified by the <code>TIMEFMT</code> parameter. If
<code>pipeline</code> is omitted, print statistics about the shell process and its
children.</p>
<p><span id="index-conditional-expression"></span>
<span id="index-_005b_005b"></span></p>
<p><code>[[</code> <code>exp</code> <code>]]</code></p>
<p>Evaluates the conditional expression <code>exp</code> and return a zero exit status
if it is true. See <a href="Conditional-Expressions.html#Conditional-Expressions">Conditional
Expressions</a> for a
description of <code>exp</code>.</p>
<hr />
<p><span id="Alternate-Forms-For-Complex-Commands"></span>
<span id="Alternate-Forms-For-Complex-Commands-1"></span></p>
<h2 id="64-alternate-forms-for-complex-commands"><a class="header" href="#64-alternate-forms-for-complex-commands">6.4 Alternate Forms For Complex Commands</a></h2>
<p><span id="index-alternate-forms-for-complex-commands"></span>
<span id="index-commands_002c-alternate-forms-for-complex"></span></p>
<p>Many of zshs complex commands have alternate forms. These are
non-standard and are likely not to be obvious even to seasoned shell
programmers; they should not be used anywhere that portability of shell
code is a concern.</p>
<p>The short versions below only work if <code>sublist</code> is of the form <code>{</code>
<code>list</code> <code>}</code> or if the <code>SHORT_LOOPS</code> option is set. For the <code>if</code>, <code>while</code>
and <code>until</code> commands, in both these cases the test part of the loop must
also be suitably delimited, such as by <code>[[</code> <code>...</code> <code>]]</code> or <code>((</code> <code>...</code>
<code>))</code>, else the end of the test will not be recognized. For the <code>for</code>,
<code>repeat</code>, <code>case</code> and <code>select</code> commands no such special form for the
arguments is necessary, but the other condition (the special form of
<code>sublist</code> or use of the <code>SHORT_LOOPS</code> option) still applies.</p>
<ul>
<li>
<p><code>if</code> <code>list</code> <code>{</code> <code>list</code> <code>}</code> [ <code>elif</code> <code>list</code> <code>{</code> <code>list</code> <code>}</code> ] ... [
<code>else {</code> <code>list</code> <code>}</code> ]<br />
An alternate form of <code>if</code>. The rules mean that</p>
<div class="example">
<pre><code class="language-example">if [[ -o ignorebraces ]] {
print yes
}
</code></pre>
</div>
<p>works, but</p>
<div class="example">
<pre><code class="language-example">if true { # Does not work!
print yes
}
</code></pre>
</div>
<p>does <em>not</em>, since the test is not suitably delimited.</p>
</li>
<li>
<p><code>if</code> <code>list</code> <code>sublist</code><br />
A short form of the alternate <code>if</code>. The same limitations on the form
of <code>list</code> apply as for the previous form.</p>
</li>
<li>
<p><code>for</code> <code>name</code> ... <code>(</code> <code>word</code> ... <code>)</code> <code>sublist</code><br />
A short form of <code>for</code>.</p>
</li>
<li>
<p><code>for</code> <code>name</code> ... [ <code>in</code> <code>word</code> ... ] <code>term</code> <code>sublist</code><br />
where <code>term</code> is at least one newline or <code>;</code>. Another short form of
<code>for</code>.</p>
</li>
<li>
<p><code>for ((</code> [<code>expr1</code>] <code>;</code> [<code>expr2</code>] <code>;</code> [<code>expr3</code>] <code>))</code>
<code>sublist</code><br />
A short form of the arithmetic <code>for</code> command.</p>
<p><span id="index-foreach"></span></p>
</li>
<li>
<p><code>foreach</code> <code>name</code> ... <code>(</code> <code>word</code> ... <code>)</code> <code>list</code> <code>end</code><br />
Another form of <code>for</code>.</p>
</li>
<li>
<p><code>while</code> <code>list</code> <code>{</code> <code>list</code> <code>}</code><br />
An alternative form of <code>while</code>. Note the limitations on the form of
<code>list</code> mentioned above.</p>
</li>
<li>
<p><code>until</code> <code>list</code> <code>{</code> <code>list</code> <code>}</code><br />
An alternative form of <code>until</code>. Note the limitations on the form of
<code>list</code> mentioned above.</p>
</li>
<li>
<p><code>repeat</code> <code>word</code> <code>sublist</code><br />
This is a short form of <code>repeat</code>.</p>
</li>
<li>
<p><code>case</code> <code>word</code> <code>{</code> [ [<code>(</code>] <code>pattern</code> [ <code>|</code> <code>pattern</code> ] ... <code>)</code>
<code>list</code> (<code>;;</code>|<code>;&amp;</code>|<code>;|</code>) ] ... <code>}</code><br />
An alternative form of <code>case</code>.</p>
</li>
<li>
<p><code>select</code> <code>name</code> [ <code>in</code> <code>word</code> ... <code>term</code> ] <code>sublist</code><br />
where <code>term</code> is at least one newline or <code>;</code>. A short form of
<code>select</code>.</p>
</li>
<li>
<p><code>function</code> <code>word</code> ... [ <code>()</code> ] [ <code>term</code> ] <code>sublist</code><br />
This is a short form of <code>function</code>.</p>
</li>
</ul>
<hr />
<p><span id="Reserved-Words"></span> <span id="Reserved-Words-1"></span></p>
<h2 id="65-reserved-words"><a class="header" href="#65-reserved-words">6.5 Reserved Words</a></h2>
<p><span id="index-reserved-words"></span>
<span id="index-disable_002c-use-of"></span></p>
<p>The following words are recognized as reserved words when used as the
first word of a command unless quoted or disabled using <code>disable -r</code>:</p>
<p><code>do done esac then elif else fi for case if while function repeat time until select coproc nocorrect foreach end ! [[ { } declare export float integer local readonly typeset</code></p>
<p>Additionally, <code>}</code> is recognized in any position if neither the
<code>IGNORE_BRACES</code> option nor the <code>IGNORE_CLOSE_BRACES</code> option is set.</p>
<hr />
<p><span id="Errors"></span> <span id="Errors-1"></span></p>
<h2 id="66-errors"><a class="header" href="#66-errors">6.6 Errors</a></h2>
<p><span id="index-errors_002c-handling-of"></span></p>
<p>Certain errors are treated as fatal by the shell: in an interactive
shell, they cause control to return to the command line, and in a
non-interactive shell they cause the shell to be aborted. In older
versions of zsh, a non-interactive shell running a script would not
abort completely, but would resume execution at the next command to be
read from the script, skipping the remainder of any functions or shell
constructs such as loops or conditions; this somewhat illogical
behaviour can be recovered by setting the option <code>CONTINUE_ON_ERROR</code>.</p>
<p>Fatal errors found in non-interactive shells include:</p>
<ul>
<li>Failure to parse shell options passed when invoking the shell</li>
<li>Failure to change options with the <code>set</code> builtin</li>
<li>Parse errors of all sorts, including failures to parse mathematical
expressions</li>
<li>Failures to set or modify variable behaviour with <code>typeset</code>,
<code>local</code>, <code>declare</code>, <code>export</code>, <code>integer</code>, <code>float</code></li>
<li>Execution of incorrectly positioned loop control structures
(<code>continue</code>, <code>break</code>)</li>
<li>Attempts to use regular expression with no regular expression module
available</li>
<li>Disallowed operations when the <code>RESTRICTED</code> options is set</li>
<li>Failure to create a pipe needed for a pipeline</li>
<li>Failure to create a multio</li>
<li>Failure to autoload a module needed for a declared shell feature</li>
<li>Errors creating command or process substitutions</li>
<li>Syntax errors in glob qualifiers</li>
<li>File generation errors where not caught by the option <code>BAD_PATTERN</code></li>
<li>All bad patterns used for matching within case statements</li>
<li>File generation failures where not caused by <code>NO_MATCH</code> or similar
options</li>
<li>All file generation errors where the pattern was used to create a
multio</li>
<li>Memory errors where detected by the shell</li>
<li>Invalid subscripts to shell variables</li>
<li>Attempts to assign read-only variables</li>
<li>Logical errors with variables such as assignment to the wrong type</li>
<li>Use of invalid variable names</li>
<li>Errors in variable substitution syntax</li>
<li>Failure to convert characters in <code>$</code>...<code></code> expressions</li>
</ul>
<p>If the <code>POSIX_BUILTINS</code> option is set, more errors associated with shell
builtin commands are treated as fatal, as specified by the POSIX
standard.</p>
<hr />
<p><span id="Comments"></span> <span id="Comments-1"></span></p>
<h2 id="67-comments"><a class="header" href="#67-comments">6.7 Comments</a></h2>
<p><span id="index-comments"></span>
<span id="index-INTERACTIVE_005fCOMMENTS_002c-use-of"></span>
<span id="index-histchars_002c-use-of"></span></p>
<p>In non-interactive shells, or in interactive shells with the
<code>INTERACTIVE_COMMENTS</code> option set, a word beginning with the third
character of the <code>histchars</code> parameter (<code>#</code> by default) causes that
word and all the following characters up to a newline to be ignored.</p>
<hr />
<p><span id="Aliasing"></span> <span id="Aliasing-1"></span></p>
<h2 id="68-aliasing"><a class="header" href="#68-aliasing">6.8 Aliasing</a></h2>
<p><span id="index-aliasing"></span></p>
<p>Every eligible <em>word</em> in the shell input is checked to see if there is
an alias defined for it. If so, it is replaced by the text of the alias
if it is in command position (if it could be the first word of a simple
command), or if the alias is global. If the replacement text ends with a
space, the next word in the shell input is always eligible for purposes
of alias expansion. <span id="index-alias_002c-use-of"></span>
<span id="index-aliases_002c-global"></span> An alias is defined using
the <code>alias</code> builtin; global aliases may be defined using the <code>-g</code> option
to that builtin.</p>
<p>A <em>word</em> is defined as:</p>
<ul>
<li>Any plain string or glob pattern</li>
<li>Any quoted string, using any quoting method (note that the quotes
must be part of the alias definition for this to be eligible)</li>
<li>Any parameter reference or command substitution</li>
<li>Any series of the foregoing, concatenated without whitespace or
other tokens between them</li>
<li>Any reserved word (<code>case</code>, <code>do</code>, <code>else</code>, etc.)</li>
<li>With global aliasing, any command separator, any redirection
operator, and <code>(</code> or <code>)</code> when not part of a glob pattern</li>
</ul>
<p>Alias expansion is done on the shell input before any other expansion
except history expansion. Therefore, if an alias is defined for the word
<code>foo</code>, alias expansion may be avoided by quoting part of the word, e.g.
<code>\foo</code>. Any form of quoting works, although there is nothing to prevent
an alias being defined for the quoted form such as <code>\foo</code> as well.</p>
<p>When <code>POSIX_ALIASES</code> is set, only plain unquoted strings are eligible
for aliasing. The <code>alias</code> builtin does not reject ineligible aliases,
but they are not expanded.</p>
<p>For use with completion, which would remove an initial backslash
followed by a character that isnt special, it may be more convenient to
quote the word by starting with a single quote, i.e. <code>foo</code>; completion
will automatically add the trailing single quote.</p>
<hr />
<p><span id="Alias-difficulties"></span></p>
<h3 id="681-alias-difficulties"><a class="header" href="#681-alias-difficulties">6.8.1 Alias difficulties</a></h3>
<p>Although aliases can be used in ways that bend normal shell syntax, not
every string of non-white-space characters can be used as an alias.</p>
<p>Any set of characters not listed as a word above is not a word, hence no
attempt is made to expand it as an alias, no matter how it is defined
(i.e. via the builtin or the special parameter <code>aliases</code> described in
<a href="Zsh-Modules.html#The-zsh_002fparameter-Module">The zsh/parameter
Module</a>). However, as
noted in the case of <code>POSIX_ALIASES</code> above, the shell does not attempt
to deduce whether the string corresponds to a word at the time the alias
is created.</p>
<p>For example, an expression containing an <code>=</code> at the start of a command
line is an assignment and cannot be expanded as an alias; a lone <code>=</code> is
not an assignment but can only be set as an alias using the parameter,
as otherwise the <code>=</code> is taken part of the syntax of the builtin command.</p>
<p>It is not presently possible to alias the <code>((</code> token that introduces
arithmetic expressions, because until a full statement has been parsed,
it cannot be distinguished from two consecutive <code>(</code> tokens introducing
nested subshells. Also, if a separator such as <code>&amp;&amp;</code> is aliased, <code>\&amp;&amp;</code>
turns into the two tokens <code>\&amp;</code> and <code>&amp;</code>, each of which may have been
aliased separately. Similarly for <code>\&lt;&lt;</code>, <code>\&gt;|</code>, etc.</p>
<p>There is a commonly encountered problem with aliases illustrated by the
following code:</p>
<div class="example">
<pre><code class="language-example">alias echobar='echo bar'; echobar
</code></pre>
</div>
<p>This prints a message that the command <code>echobar</code> could not be found.
This happens because aliases are expanded when the code is read in; the
entire line is read in one go, so that when <code>echobar</code> is executed it is
too late to expand the newly defined alias. This is often a problem in
shell scripts, functions, and code executed with <code>source</code> or <code>.</code>.
Consequently, use of functions rather than aliases is recommended in
non-interactive code.</p>
<p>Note also the unhelpful interaction of aliases and function definitions:</p>
<div class="example">
<pre><code class="language-example">alias func='noglob func'
func() {
echo Do something with $*
}
</code></pre>
</div>
<p>Because aliases are expanded in function definitions, this causes the
following command to be executed:</p>
<div class="example">
<pre><code class="language-example">noglob func() {
echo Do something with $*
}
</code></pre>
</div>
<p>which defines <code>noglob</code> as well as <code>func</code> as functions with the body
given. To avoid this, either quote the name <code>func</code> or use the
alternative function definition form <code>function func</code>. Ensuring the
alias is defined after the function works but is problematic if the code
fragment might be re-executed.</p>
<hr />
<p><span id="Quoting"></span> <span id="Quoting-1"></span></p>
<h2 id="69-quoting"><a class="header" href="#69-quoting">6.9 Quoting</a></h2>
<p><span id="index-quoting"></span></p>
<p>A character may be <em>quoted</em> (that is, made to stand for itself) by
preceding it with a <code>\</code>. <code>\</code> followed by a newline is ignored.</p>
<p>A string enclosed between <code>$</code> and <code></code> is processed the same way as
the string arguments of the <code>print</code> builtin, and the resulting string is
considered to be entirely quoted. A literal <code></code> character can be
included in the string by using the <code>\</code> escape.</p>
<p><span id="index-RC_005fQUOTES_002c-use-of"></span></p>
<p>All characters enclosed between a pair of single quotes (<code></code>) that is
not preceded by a <code>$</code> are quoted. A single quote cannot appear within
single quotes unless the option <code>RC_QUOTES</code> is set, in which case a pair
of single quotes are turned into a single quote. For example,</p>
<div class="example">
<pre><code class="language-example">print ''''
</code></pre>
</div>
<p>outputs nothing apart from a newline if <code>RC_QUOTES</code> is not set, but one
single quote if it is set.</p>
<p>Inside double quotes (<code>&quot;&quot;</code>), parameter and command substitution occur,
and <code>\</code> quotes the characters <code>\</code>, <code></code>, <code>&quot;</code>, <code>$</code>, and the
first character of <code>$histchars</code> (default <code>!</code>).</p>
<hr />
<p>This document was generated on <em>February 15, 2020</em> using
<a href="http://www.nongnu.org/texi2html/"><em>texi2html 5.0</em></a>.<br />
Zsh version 5.8, released on February 14, 2020.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="Files.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="Redirection.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="Files.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="Redirection.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>
<!-- Livereload script (if served using the cli tool) -->
<script type="text/javascript">
var socket = new WebSocket("ws://localhost:3000/__livereload");
socket.onmessage = function (event) {
if (event.data === "reload") {
socket.close();
location.reload();
}
};
window.onbeforeunload = function() {
socket.close();
}
</script>
<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>

View File

@ -0,0 +1,962 @@
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>TCP Function System - Zsh Manual</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 -->
</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 "><a href="The-Z-Shell-Manual.html"><strong aria-hidden="true">1.</strong> The Z Shell Manual</a></li><li class="chapter-item expanded "><a href="Introduction.html"><strong aria-hidden="true">2.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="Roadmap.html"><strong aria-hidden="true">3.</strong> Roadmap</a></li><li class="chapter-item expanded "><a href="Invocation.html"><strong aria-hidden="true">4.</strong> Invocation</a></li><li class="chapter-item expanded "><a href="Files.html"><strong aria-hidden="true">5.</strong> Files</a></li><li class="chapter-item expanded "><a href="Shell-Grammar.html"><strong aria-hidden="true">6.</strong> Shell Grammar</a></li><li class="chapter-item expanded "><a href="Redirection.html"><strong aria-hidden="true">7.</strong> Redirection</a></li><li class="chapter-item expanded "><a href="Command-Execution.html"><strong aria-hidden="true">8.</strong> Command Execution</a></li><li class="chapter-item expanded "><a href="Functions.html"><strong aria-hidden="true">9.</strong> Functions</a></li><li class="chapter-item expanded "><a href="Jobs-_0026-Signals.html"><strong aria-hidden="true">10.</strong> Jobs &amp; Signals</a></li><li class="chapter-item expanded "><a href="Arithmetic-Evaluation.html"><strong aria-hidden="true">11.</strong> Arithmetic Evaluation</a></li><li class="chapter-item expanded "><a href="Conditional-Expressions.html"><strong aria-hidden="true">12.</strong> Conditional Expressions</a></li><li class="chapter-item expanded "><a href="Prompt-Expansion.html"><strong aria-hidden="true">13.</strong> Prompt Expansion</a></li><li class="chapter-item expanded "><a href="Expansion.html"><strong aria-hidden="true">14.</strong> Expansion</a></li><li class="chapter-item expanded "><a href="Parameters.html"><strong aria-hidden="true">15.</strong> Parameters</a></li><li class="chapter-item expanded "><a href="Options.html"><strong aria-hidden="true">16.</strong> Options</a></li><li class="chapter-item expanded "><a href="Shell-Builtin-Commands.html"><strong aria-hidden="true">17.</strong> Shell Builtin Commands</a></li><li class="chapter-item expanded "><a href="Zsh-Line-Editor.html"><strong aria-hidden="true">18.</strong> Zsh Line Editor</a></li><li class="chapter-item expanded "><a href="Completion-Widgets.html"><strong aria-hidden="true">19.</strong> Completion Widgets</a></li><li class="chapter-item expanded "><a href="Completion-System.html"><strong aria-hidden="true">20.</strong> Completion System</a></li><li class="chapter-item expanded "><a href="Completion-Using-compctl.html"><strong aria-hidden="true">21.</strong> Completion Using compctl</a></li><li class="chapter-item expanded "><a href="Zsh-Modules.html"><strong aria-hidden="true">22.</strong> Zsh Modules</a></li><li class="chapter-item expanded "><a href="Calendar-Function-System.html"><strong aria-hidden="true">23.</strong> Calendar Function System</a></li><li class="chapter-item expanded "><a href="TCP-Function-System.html" class="active"><strong aria-hidden="true">24.</strong> TCP Function System</a></li><li class="chapter-item expanded "><a href="Zftp-Function-System.html"><strong aria-hidden="true">25.</strong> Zftp Function System</a></li><li class="chapter-item expanded "><a href="User-Contributions.html"><strong aria-hidden="true">26.</strong> User Contributions</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>
</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 Manual</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" name="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="#24-tcp-function-system">24 TCP Function System</a>
<ul>
<li><a href="#241-description">24.1 Description</a></li>
<li><a href="#242-tcp-user-functions">24.2 TCP User Functions</a>
<ul>
<li><a href="#2421-basic-io">24.2.1 Basic I/O</a></li>
<li><a href="#2422-session-management">24.2.2 Session Management</a></li>
<li><a href="#2423-advanced-io">24.2.3 Advanced I/O</a></li>
<li><a href="#2424-one-shot-file-transfer">24.2.4 One-shot file transfer</a></li>
</ul>
</li>
<li><a href="#243-tcp-user-defined-functions">24.3 TCP User-defined Functions</a></li>
<li><a href="#244-tcp-utility-functions">24.4 TCP Utility Functions</a></li>
<li><a href="#245-tcp-user-parameters">24.5 TCP User Parameters</a></li>
<li><a href="#246-tcp-user-defined-parameters">24.6 TCP User-defined Parameters</a></li>
<li><a href="#247-tcp-utility-parameters">24.7 TCP Utility Parameters</a></li>
<li><a href="#248-tcp-examples">24.8 TCP Examples</a></li>
<li><a href="#249-tcp-bugs">24.9 TCP Bugs</a></li>
</ul>
</li>
</ul>
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<p><span id="TCP-Function-System"></span>
<span id="TCP-Function-System-1"></span></p>
<h1 id="24-tcp-function-system"><a class="header" href="#24-tcp-function-system">24 TCP Function System</a></h1>
<p><span id="index-TCP-function-system"></span>
<span id="index-ztcp_002c-function-system-based-on"></span></p>
<hr />
<p><span id="Description"></span></p>
<h2 id="241-description"><a class="header" href="#241-description">24.1 Description</a></h2>
<p>A module <code>zsh/net/tcp</code> is provided to provide network I/O over TCP/IP
from within the shell; see its description in <a href="Zsh-Modules.html#Zsh-Modules">Zsh
Modules</a>. This manual page describes a
function suite based on the module. If the module is installed, the
functions are usually installed at the same time, in which case they
will be available for autoloading in the default function search path.
In addition to the <code>zsh/net/tcp</code> module, the <code>zsh/zselect</code> module is
used to implement timeouts on read operations. For troubleshooting tips,
consult the corresponding advice for the <code>zftp</code> functions described in
<a href="Zftp-Function-System.html#Zftp-Function-System">Zftp Function System</a>.</p>
<p>There are functions corresponding to the basic I/O operations open,
close, read and send, named <code>tcp_open</code> etc., as well as a function
<code>tcp_expect</code> for pattern match analysis of data read as input. The
system makes it easy to receive data from and send data to multiple
named sessions at once. In addition, it can be linked with the shells
line editor in such a way that input data is automatically shown at the
terminal. Other facilities available including logging, filtering and
configurable output prompts.</p>
<p>To use the system where it is available, it should be enough to
<code>autoload -U tcp_open</code> and run <code>tcp_open</code> as documented below to
start a session. The <code>tcp_open</code> function will autoload the remaining
functions.</p>
<hr />
<p><span id="TCP-Functions"></span> <span id="TCP-User-Functions"></span></p>
<h2 id="242-tcp-user-functions"><a class="header" href="#242-tcp-user-functions">24.2 TCP User Functions</a></h2>
<hr />
<p><span id="Basic-I_002fO"></span></p>
<h3 id="2421-basic-io"><a class="header" href="#2421-basic-io">24.2.1 Basic I/O</a></h3>
<p><span id="index-tcp_005fopen"></span></p>
<p><code>tcp_open</code> [ <code>-qz</code> ] <code>host port</code> [ <code>sess</code> ]</p>
<p><code>tcp_open</code> [ <code>-qz</code> ] [ <code>-s</code> <code>sess</code> | <code>-l</code> <code>sess</code>[<code>,</code>...] ] ...</p>
<p><code>tcp_open</code> [ <code>-qz</code> ] [ <code>-a</code> <code>fd</code> | <code>-f</code> <code>fd</code> ] [ <code>sess</code> ]</p>
<p>Open a new session. In the first and simplest form, open a TCP
connection to host <code>host</code> at port <code>port</code>; numeric and symbolic forms are
understood for both.</p>
<p>If <code>sess</code> is given, this becomes the name of the session which can be
used to refer to multiple different TCP connections. If <code>sess</code> is not
given, the function will invent a numeric name value (note this is <em>not</em>
the same as the file descriptor to which the session is attached). It is
recommended that session names not include funny characters, where
funny characters are not well-defined but certainly do not include
alphanumerics or underscores, and certainly do include whitespace.</p>
<p>In the second case, one or more sessions to be opened are given by name.
A single session name is given after <code>-s</code> and a comma-separated list
after <code>-l</code>; both options may be repeated as many times as necessary. A
failure to open any session causes <code>tcp_open</code> to abort. The host and
port are read from the file <code>.ztcp_sessions</code> in the same directory as
the users zsh initialisation files, i.e. usually the home directory,
but <code>$ZDOTDIR</code> if that is set. The file consists of lines each giving a
session name and the corresponding host and port, in that order (note
the session name comes first, not last), separated by whitespace.</p>
<p>The third form allows passive and fake TCP connections. If the option
<code>-a</code> is used, its argument is a file descriptor open for listening for
connections. No function front-end is provided to open such a file
descriptor, but a call to <code>ztcp -l</code> <code>port</code> will create one with the
file descriptor stored in the parameter <code>$REPLY</code>. The listening port can
be closed with <code>ztcp -c</code> <code>fd</code>. A call to <code>tcp_open -a</code> <code>fd</code> will
block until a remote TCP connection is made to <code>port</code> on the local
machine. At this point, a session is created in the usual way and is
largely indistinguishable from an active connection created with one of
the first two forms.</p>
<p>If the option <code>-f</code> is used, its argument is a file descriptor which is
used directly as if it were a TCP session. How well the remainder of the
TCP function system copes with this depends on what actually underlies
this file descriptor. A regular file is likely to be unusable; a FIFO
(pipe) of some sort will work better, but note that it is not a good
idea for two different sessions to attempt to read from the same FIFO at
once.</p>
<p>If the option <code>-q</code> is given with any of the three forms, <code>tcp_open</code> will
not print informational messages, although it will in any case exit with
an appropriate status.</p>
<p>If the line editor (zle) is in use, which is typically the case if the
shell is interactive, <code>tcp_open</code> installs a handler inside zle which
will check for new data at the same time as it checks for keyboard
input. This is convenient as the shell consumes no CPU time while
waiting; the test is performed by the operating system. Giving the
option <code>-z</code> to any of the forms of <code>tcp_open</code> prevents the handler from
being installed, so data must be read explicitly. Note, however, this is
not necessary for executing complete sets of send and read commands from
a function, as zle is not active at this point. Generally speaking, the
handler is only active when the shell is waiting for input at a command
prompt or in the <code>vared</code> builtin. The option has no effect if zle is not
active; <code>[[ -o zle]]</code> will test for this.</p>
<p>The first session to be opened becomes the current session and
subsequent calls to <code>tcp_open</code> do not change it. The current session is
stored in the parameter <code>$TCP_SESS</code>; see below for more detail about the
parameters used by the system.</p>
<p>The function <code>tcp_on_open</code>, if defined, is called when a session is
opened. See the description below.</p>
<p><span id="index-tcp_005fclose"></span></p>
<p><code>tcp_close</code> [ <code>-qn</code> ] [ <code>-a</code> | <code>-l</code> <code>sess</code>[<code>,</code>...] | <code>sess</code> ... ]</p>
<p>Close the named sessions, or the current session if none is given, or
all open sessions if <code>-a</code> is given. The options <code>-l</code> and <code>-s</code> are both
handled for consistency with <code>tcp_open</code>, although the latter is
redundant.</p>
<p>If the session being closed is the current one, <code>$TCP_SESS</code> is unset,
leaving no current session, even if there are other sessions still open.</p>
<p>If the session was opened with <code>tcp_open -f</code>, the file descriptor is
closed so long as it is in the range 0 to 9 accessible directly from the
command line. If the option <code>-n</code> is given, no attempt will be made to
close file descriptors in this case. The <code>-n</code> option is not used for
genuine <code>ztcp</code> session; the file descriptors are always closed with the
session.</p>
<p>If the option <code>-q</code> is given, no informational messages will be printed.</p>
<p><span id="index-tcp_005fread"></span></p>
<p><code>tcp_read </code>[ <code>-bdq</code> ] [ <code>-t</code> <code>TO</code> ] [ <code>-T</code> <code>TO</code> ]</p>
<p><code>         </code>[ <code>-a</code> | <code>-u</code> <code>fd</code>[<code>,</code>...] | <code>-l</code> <code>sess</code>[<code>,</code>...] | <code>-s</code>
<code>sess</code> ... ]</p>
<p>Perform a read operation on the current session, or on a list of
sessions if any are given with <code>-u</code>, <code>-l</code> or <code>-s</code>, or all open sessions
if the option <code>-a</code> is given. Any of the <code>-u</code>, <code>-l</code> or <code>-s</code> options may
be repeated or mixed together. The <code>-u</code> option specifies a file
descriptor directly (only those managed by this system are useful), the
other two specify sessions as described for <code>tcp_open</code> above.</p>
<p>The function checks for new data available on all the sessions listed.
Unless the <code>-b</code> option is given, it will not block waiting for new data.
Any one line of data from any of the available sessions will be read,
stored in the parameter <code>$TCP_LINE</code>, and displayed to standard output
unless <code>$TCP_SILENT</code> contains a non-empty string. When printed to
standard output the string <code>$TCP_PROMPT</code> will be shown at the start of
the line; the default form for this includes the name of the session
being read. See below for more information on these parameters. In this
mode, <code>tcp_read</code> can be called repeatedly until it returns status 2
which indicates all pending input from all specified sessions has been
handled.</p>
<p>With the option <code>-b</code>, equivalent to an infinite timeout, the function
will block until a line is available to read from one of the specified
sessions. However, only a single line is returned.</p>
<p>The option <code>-d</code> indicates that all pending input should be drained. In
this case <code>tcp_read</code> may process multiple lines in the manner given
above; only the last is stored in <code>$TCP_LINE</code>, but the complete set is
stored in the array <code>$tcp_lines</code>. This is cleared at the start of each
call to <code>tcp_read</code>.</p>
<p>The options <code>-t</code> and <code>-T</code> specify a timeout in seconds, which may be a
floating point number for increased accuracy. With <code>-t</code> the timeout is
applied before each line read. With <code>-T</code>, the timeout applies to the
overall operation, possibly including multiple read operations if the
option <code>-d</code> is present; without this option, there is no distinction
between <code>-t</code> and <code>-T</code>.</p>
<p>The function does not print informational messages, but if the option
<code>-q</code> is given, no error message is printed for a non-existent session.</p>
<p>A return status of 2 indicates a timeout or no data to read. Any other
non-zero return status indicates some error condition.</p>
<p>See <code>tcp_log</code> for how to control where data is sent by <code>tcp_read</code>.</p>
<p><span id="index-tcp_005fsend"></span></p>
<p><code>tcp_send</code> [ <code>-cnq</code> ] [ <code>-s</code> <code>sess</code> | <code>-l</code> <code>sess</code>[<code>,</code>...] ] <code>data</code>
...</p>
<p><code>tcp_send</code> [ <code>-cnq</code> ] <code>-a</code> <code>data</code> ...</p>
<p>Send the supplied data strings to all the specified sessions in turn.
The underlying operation differs little from a <code>print -r</code> to the
sessions file descriptor, although it attempts to prevent the shell
from dying owing to a <code>SIGPIPE</code> caused by an attempt to write to a
defunct session.</p>
<p>The option <code>-c</code> causes <code>tcp_send</code> to behave like <code>cat</code>. It reads lines
from standard input until end of input and sends them in turn to the
specified session(s) exactly as if they were given as <code>data</code> arguments
to individual <code>tcp_send</code> commands.</p>
<p>The option <code>-n</code> prevents <code>tcp_send</code> from putting a newline at the end of
the data strings.</p>
<p>The remaining options all behave as for <code>tcp_read</code>.</p>
<p>The data arguments are not further processed once they have been passed
to <code>tcp_send</code>; they are simply passed down to <code>print -r</code>.</p>
<p>If the parameter <code>$TCP_OUTPUT</code> is a non-empty string and logging is
enabled then the data sent to each session will be echoed to the log
file(s) with <code>$TCP_OUTPUT</code> in front where appropriate, much in the
manner of <code>$TCP_PROMPT</code>.</p>
<hr />
<p><span id="Session-Management"></span></p>
<h3 id="2422-session-management"><a class="header" href="#2422-session-management">24.2.2 Session Management</a></h3>
<p><span id="index-tcp_005falias"></span></p>
<p><code>tcp_alias</code> [ <code>-q</code> ] <code>alias``=``sess</code> ...</p>
<p><code>tcp_alias</code> [ <code>-q</code> ] [ <code>alias</code> ... ]</p>
<p><code>tcp_alias</code> <code>-d</code> [ <code>-q</code> ] <code>alias</code> ...</p>
<p>This function is not particularly well tested.</p>
<p>The first form creates an alias for a session name; <code>alias</code> can then be
used to refer to the existing session <code>sess</code>. As many aliases may be
listed as required.</p>
<p>The second form lists any aliases specified, or all aliases if none.</p>
<p>The third form deletes all the aliases listed. The underlying sessions
are not affected.</p>
<p>The option <code>-q</code> suppresses an inconsistently chosen subset of error
messages.</p>
<p><span id="index-tcp_005flog"></span></p>
<p><code>tcp_log</code> [ <code>-asc</code> ] [ <code>-n</code> | <code>-N</code> ] [ <code>logfile</code> ]</p>
<p>With an argument <code>logfile</code>, all future input from <code>tcp_read</code> will be
logged to the named file. Unless <code>-a</code> (append) is given, this file will
first be truncated or created empty. With no arguments, show the current
status of logging.</p>
<p>With the option <code>-s</code>, per-session logging is enabled. Input from
<code>tcp_read</code> is output to the file <code>logfile``.``sess</code>. As the session is
automatically discriminated by the filename, the contents are raw (no
<code>$TCP_PROMPT</code>). The option <code>-a</code> applies as above. Per-session logging
and logging of all data in one file are not mutually exclusive.</p>
<p>The option <code>-c</code> closes all logging, both complete and per-session logs.</p>
<p>The options <code>-n</code> and <code>-N</code> respectively turn off or restore output of
data read by <code>tcp_read</code> to standard output; hence <code>tcp_log -cn</code> turns
off all output by <code>tcp_read</code>.</p>
<p>The function is purely a convenient front end to setting the parameters
<code>$TCP_LOG</code>, <code>$TCP_LOG_SESS</code>, <code>$TCP_SILENT</code>, which are described below.</p>
<p><span id="index-tcp_005frename"></span></p>
<p><code>tcp_rename</code> <code>old</code> <code>new</code></p>
<p>Rename session <code>old</code> to session <code>new</code>. The old name becomes invalid.</p>
<p><span id="index-tcp_005fsess"></span></p>
<p><code>tcp_sess</code> [ <code>sess</code> [ <code>command</code> [ <code>arg</code> ... ] ] ]</p>
<p>With no arguments, list all the open sessions and associated file
descriptors. The current session is marked with a star. For use in
functions, direct access to the parameters <code>$tcp_by_name</code>, <code>$tcp_by_fd</code>
and <code>$TCP_SESS</code> is probably more convenient; see below.</p>
<p>With a <code>sess</code> argument, set the current session to <code>sess</code>. This is
equivalent to changing <code>$TCP_SESS</code> directly.</p>
<p>With additional arguments, temporarily set the current session while
executing <code>command</code> <code>arg</code> .... <code>command</code> is re-evaluated so as to
expand aliases etc., but the remaining <code>arg</code>s are passed through as that
appear to <code>tcp_sess</code>. The original session is restored when <code>tcp_sess</code>
exits.</p>
<hr />
<p><span id="Advanced-I_002fO"></span></p>
<h3 id="2423-advanced-io"><a class="header" href="#2423-advanced-io">24.2.3 Advanced I/O</a></h3>
<p><span id="index-tcp_005fcommand"></span></p>
<p><code>tcp_command</code> <code>send-option</code> ... <code>send-argument</code> ...</p>
<p>This is a convenient front-end to <code>tcp_send</code>. All arguments are passed
to <code>tcp_send</code>, then the function pauses waiting for data. While data is
arriving at least every <code>$TCP_TIMEOUT</code> (default 0.3) seconds, data is
handled and printed out according to the current settings. Status 0 is
always returned.</p>
<p>This is generally only useful for interactive use, to prevent the
display becoming fragmented by output returned from the connection.
Within a programme or function it is generally better to handle reading
data by a more explicit method.</p>
<p><span id="index-tcp_005fexpect"></span></p>
<p><code>tcp_expect </code>[ <code>-q</code> ] [ <code>-p</code> <code>var</code> | <code>-P</code> <code>var</code> ] [ <code>-t</code> <code>TO</code> |
<code>-T</code> <code>TO</code> ]</p>
<p><code>           </code>[ <code>-a</code> | <code>-s</code> <code>sess</code> | <code>-l</code> <code>sess</code>[<code>,</code>...] ] <code>pattern</code>
...</p>
<p>Wait for input matching any of the given <code>pattern</code>s from any of the
specified sessions. Input is ignored until an input line matches one of
the given patterns; at this point status zero is returned, the matching
line is stored in <code>$TCP_LINE</code>, and the full set of lines read during the
call to <code>tcp_expect</code> is stored in the array <code>$tcp_expect_lines</code>.</p>
<p>Sessions are specified in the same way as <code>tcp_read</code>: the default is to
use the current session, otherwise the sessions specified by <code>-a</code>, <code>-s</code>,
or <code>-l</code> are used.</p>
<p>Each <code>pattern</code> is a standard zsh extended-globbing pattern; note that it
needs to be quoted to avoid it being expanded immediately by filename
generation. It must match the full line, so to match a substring there
must be a <code>*</code> at the start and end. The line matched against includes
the <code>$TCP_PROMPT</code> added by <code>tcp_read</code>. It is possible to include the
globbing flags <code>#b</code> or <code>#m</code> in the patterns to make backreferences
available in the parameters <code>$MATCH</code>, <code>$match</code>, etc., as described in
the base zsh documentation on pattern matching.</p>
<p>Unlike <code>tcp_read</code>, the default behaviour of <code>tcp_expect</code> is to block
indefinitely until the required input is found. This can be modified by
specifying a timeout with <code>-t</code> or <code>-T</code>; these function as in <code>tcp_read</code>,
specifying a per-read or overall timeout, respectively, in seconds, as
an integer or floating-point number. As <code>tcp_read</code>, the function returns
status 2 if a timeout occurs.</p>
<p>The function returns as soon as any one of the patterns given match. If
the caller needs to know which of the patterns matched, the option <code>-p</code>
<code>var</code> can be used; on return, <code>$var</code> is set to the number of the pattern
using ordinary zsh indexing, i.e. the first is 1, and so on. Note the
absence of a <code>$</code> in front of <code>var</code>. To avoid clashes, the parameter
cannot begin with <code>_expect</code>. The index -1 is used if there is a
timeout and 0 if there is no match.</p>
<p>The option <code>-P</code> <code>var</code> works similarly to <code>-p</code>, but instead of numerical
indexes the regular arguments must begin with a prefix followed by a
colon: that prefix is then used as a tag to which <code>var</code> is set when the
argument matches. The tag <code>timeout</code> is used if there is a timeout and
the empty string if there is no match. Note it is matches do not need to
be distinguished.</p>
<p>The option <code>-q</code> is passed directly down to <code>tcp_read</code>.</p>
<p>As all input is done via <code>tcp_read</code>, all the usual rules about output of
lines read apply. One exception is that the parameter <code>$tcp_lines</code> will
only reflect the line actually matched by <code>tcp_expect</code>; use
<code>$tcp_expect_lines</code> for the full set of lines read during the function
call.</p>
<p><span id="index-tcp_005fproxy"></span></p>
<p><code>tcp_proxy</code></p>
<p>This is a simple-minded function to accept a TCP connection and execute
a command with I/O redirected to the connection. Extreme caution should
be taken as there is no security whatsoever and this can leave your
computer open to the world. Ideally, it should only be used behind a
firewall.</p>
<p>The first argument is a TCP port on which the function will listen.</p>
<p>The remaining arguments give a command and its arguments to execute with
standard input, standard output and standard error redirected to the
file descriptor on which the TCP session has been accepted. If no
command is given, a new zsh is started. This gives everyone on your
network direct access to your account, which in many cases will be a bad
thing.</p>
<p>The command is run in the background, so <code>tcp_proxy</code> can then accept new
connections. It continues to accept new connections until interrupted.</p>
<p><span id="index-tcp_005fspam"></span></p>
<p><code>tcp_spam</code> [ <code>-ertv</code> ] [ <code>-a</code> | <code>-s</code> <code>sess</code> | <code>-l</code> <code>sess</code>[<code>,</code>...]
] <code>cmd</code> [ <code>arg</code> ... ]</p>
<p>Execute <code>cmd</code> [ <code>arg</code> ... ] for each session in turn. Note this
executes the command and arguments; it does not send the command line as
data unless the <code>-t</code> (transmit) option is given.</p>
<p>The sessions may be selected explicitly with the standard <code>-a</code>, <code>-s</code> or
<code>-l</code> options, or may be chosen implicitly. If none of the three options
is given the rules are: first, if the array <code>$tcp_spam_list</code> is set,
this is taken as the list of sessions, otherwise all sessions are taken.
Second, any sessions given in the array <code>$tcp_no_spam_list</code> are removed
from the list of sessions.</p>
<p>Normally, any sessions added by the <code>-a</code> flag or when all sessions are
chosen implicitly are spammed in alphabetic order; sessions given by the
<code>$tcp_spam_list</code> array or on the command line are spammed in the order
given. The <code>-r</code> flag reverses the order however it was arrived it.</p>
<p>The <code>-v</code> flag specifies that a <code>$TCP_PROMPT</code> will be output before each
session. This is output after any modification to <code>TCP_SESS</code> by the
user-defined <code>tcp_on_spam</code> function described below. (Obviously that
function is able to generate its own output.)</p>
<p>If the option <code>-e</code> is present, the line given as <code>cmd</code> [ <code>arg</code> ... ]
is executed using <code>eval</code>, otherwise it is executed without any further
processing.</p>
<p><span id="index-tcp_005ftalk"></span></p>
<p><code>tcp_talk</code></p>
<p>This is a fairly simple-minded attempt to force input to the line editor
to go straight to the default <code>TCP_SESS</code>.</p>
<p>An escape string, <code>$TCP_TALK_ESCAPE</code>, default <code>:</code>, is used to allow
access to normal shell operation. If it is on its own at the start of
the line, or followed only by whitespace, the line editor returns to
normal operation. Otherwise, the string and any following whitespace are
skipped and the remainder of the line executed as shell input without
any change of the line editors operating mode.</p>
<p>The current implementation is somewhat deficient in terms of use of the
command history. For this reason, many users will prefer to use some
form of alternative approach for sending data easily to the current
session. One simple approach is to alias some special character (such as
<code>%</code>) to <code>tcp_command -``-</code>.</p>
<p><span id="index-tcp_005fwait"></span></p>
<p><code>tcp_wait</code></p>
<p>The sole argument is an integer or floating point number which gives the
seconds to delay. The shell will do nothing for that period except wait
for input on all TCP sessions by calling <code>tcp_read -a</code>. This is similar
to the interactive behaviour at the command prompt when zle handlers are
installed.</p>
<hr />
<p><span id="g_t_0060One_002dshot_0027-file-transfer"></span></p>
<h3 id="2424-one-shot-file-transfer"><a class="header" href="#2424-one-shot-file-transfer">24.2.4 One-shot file transfer</a></h3>
<ul>
<li>
<p><code>tcp_point</code> <code>port</code><br />
<code>tcp_shoot</code> <code>host</code> <code>port</code><br />
This pair of functions provide a simple way to transfer a file
between two hosts within the shell. Note, however, that bulk data
transfer is currently done using <code>cat</code>. <code>tcp_point</code> reads any data
arriving at <code>port</code> and sends it to standard output; <code>tcp_shoot</code>
connects to <code>port</code> on <code>host</code> and sends its standard input. Any
unused <code>port</code> may be used; the standard mechanism for picking a port
is to think of a random four-digit number above 1024 until one
works.</p>
<p>To transfer a file from host <code>woodcock</code> to host <code>springes</code>, on
<code>springes</code>:</p>
<div class="example">
<pre><code class="language-example">tcp_point 8091 &gt;output_file
</code></pre>
</div>
<p>and on <code>woodcock</code>:</p>
<div class="example">
<pre><code class="language-example">tcp_shoot springes 8091 &lt;input_file
</code></pre>
</div>
<p>As these two functions do not require <code>tcp_open</code> to set up a TCP
connection first, they may need to be autoloaded separately.</p>
</li>
</ul>
<hr />
<p><span id="TCP-User_002ddefined-Functions"></span></p>
<h2 id="243-tcp-user-defined-functions"><a class="header" href="#243-tcp-user-defined-functions">24.3 TCP User-defined Functions</a></h2>
<p>Certain functions, if defined by the user, will be called by the
function system in certain contexts. This facility depends on the module
<code>zsh/parameter</code>, which is usually available in interactive shells as the
completion system depends on it. None of the functions need be defined;
they simply provide convenient hooks when necessary.</p>
<p>Typically, these are called after the requested action has been taken,
so that the various parameters will reflect the new state.</p>
<p><span id="index-tcp_005fon_005falias"></span></p>
<p><code>tcp_on_alias</code> <code>alias</code> <code>fd</code></p>
<p>When an alias is defined, this function will be called with two
arguments: the name of the alias, and the file descriptor of the
corresponding session.</p>
<p><span id="index-tcp_005fon_005fawol"></span></p>
<p><code>tcp_on_awol</code> <code>sess</code> <code>fd</code></p>
<p>If the function <code>tcp_fd_handler</code> is handling input from the line editor
and detects that the file descriptor is no longer reusable, by default
it removes it from the list of file descriptors handled by this method
and prints a message. If the function <code>tcp_on_awol</code> is defined it is
called immediately before this point. It may return status 100, which
indicates that the normal handling should still be performed; any other
return status indicates that no further action should be taken and the
<code>tcp_fd_handler</code> should return immediately with the given status.
Typically the action of <code>tcp_on_awol</code> will be to close the session.</p>
<p>The variable <code>TCP_INVALIDATE_ZLE</code> will be a non-empty string if it is
necessary to invalidate the line editor display using <code>zle -I</code> before
printing output from the function.</p>
<p>(AWOL is military jargon for absent without leave or some variation.
It has no pre-existing technical meaning known to the author.)</p>
<p><span id="index-tcp_005fon_005fclose"></span></p>
<p><code>tcp_on_close</code> <code>sess</code> <code>fd</code></p>
<p>This is called with the name of a session being closed and the file
descriptor which corresponded to that session. Both will be invalid by
the time the function is called.</p>
<p><span id="index-tcp_005fon_005fopen"></span></p>
<p><code>tcp_on_open</code> <code>sess</code> <code>fd</code></p>
<p>This is called after a new session has been defined with the session
name and file descriptor as arguments. If it returns a non-zero status,
opening the session is assumed to fail and the session is closed again;
however, <code>tcp_open</code> will continue to attempt to open any remaining
sessions given on the command line.</p>
<p><span id="index-tcp_005fon_005frename"></span></p>
<p><code>tcp_on_rename</code> <code>oldsess</code> <code>fd</code> <code>newsess</code></p>
<p>This is called after a session has been renamed with the three arguments
old session name, file descriptor, new session name.</p>
<p><span id="index-tcp_005fon_005fspam"></span></p>
<p><code>tcp_on_spam</code> <code>sess</code> <code>command ...</code></p>
<p>This is called once for each session spammed, just <em>before</em> a command is
executed for a session by <code>tcp_spam</code>. The arguments are the session name
followed by the command list to be executed. If <code>tcp_spam</code> was called
with the option <code>-t</code>, the first command will be <code>tcp_send</code>.</p>
<p>This function is called after <code>$TCP_SESS</code> is set to reflect the session
to be spammed, but before any use of it is made. Hence it is possible to
alter the value of <code>$TCP_SESS</code> within this function. For example, the
session arguments to <code>tcp_spam</code> could include extra information to be
stripped off and processed in <code>tcp_on_spam</code>.</p>
<p>If the function sets the parameter <code>$REPLY</code> to <code>done</code>, the command
line is not executed; in addition, no prompt is printed for the <code>-v</code>
option to <code>tcp_spam</code>.</p>
<p><span id="index-tcp_005fon_005funalias"></span></p>
<p><code>tcp_on_unalias</code> <code>alias</code> <code>fd</code></p>
<p>This is called with the name of an alias and the corresponding sessions
file descriptor after an alias has been deleted.</p>
<hr />
<p><span id="TCP-Utility-Functions"></span></p>
<h2 id="244-tcp-utility-functions"><a class="header" href="#244-tcp-utility-functions">24.4 TCP Utility Functions</a></h2>
<p>The following functions are used by the TCP function system but will
rarely if ever need to be called directly.</p>
<p><span id="index-tcp_005ffd_005fhandler"></span></p>
<p><code>tcp_fd_handler</code></p>
<p>This is the function installed by <code>tcp_open</code> for handling input from
within the line editor, if that is required. It is in the format
documented for the builtin <code>zle -F</code> in <a href="Zsh-Line-Editor.html#Zle-Builtins">Zle
Builtins</a> .</p>
<p>While active, the function sets the parameter <code>TCP_HANDLER_ACTIVE</code> to 1.
This allows shell code called internally (for example, by setting
<code>tcp_on_read</code>) to tell if is being called when the shell is otherwise
idle at the editor prompt.</p>
<p><span id="index-tcp_005foutput"></span></p>
<p><code>tcp_output</code> [ <code>-q</code> ] <code>-P</code> <code>prompt</code> <code>-F</code> <code>fd</code> <code>-S</code> <code>sess</code></p>
<p>This function is used for both logging and handling output to standard
output, from within <code>tcp_read</code> and (if <code>$TCP_OUTPUT</code> is set) <code>tcp_send</code>.</p>
<p>The <code>prompt</code> to use is specified by <code>-P</code>; the default is the empty
string. It can contain:</p>
<ul>
<li>
<p><code>%c</code><br />
Expands to 1 if the session is the current session, otherwise 0.
Used with ternary expressions such as <code>%(c.-.+)</code> to output <code>+</code>
for the current session and <code>-</code> otherwise.</p>
</li>
<li>
<p><code>%f</code><br />
Replaced by the sessions file descriptor.</p>
</li>
<li>
<p><code>%s</code><br />
Replaced by the session name.</p>
</li>
<li>
<p><code>%%</code><br />
Replaced by a single <code>%</code>.</p>
</li>
</ul>
<p>The option <code>-q</code> suppresses output to standard output, but not to any log
files which are configured.</p>
<p>The <code>-S</code> and <code>-F</code> options are used to pass in the session name and file
descriptor for possible replacement in the prompt.</p>
<hr />
<p><span id="TCP-Parameters"></span> <span id="TCP-User-Parameters"></span></p>
<h2 id="245-tcp-user-parameters"><a class="header" href="#245-tcp-user-parameters">24.5 TCP User Parameters</a></h2>
<p>Parameters follow the usual convention that uppercase is used for
scalars and integers, while lowercase is used for normal and associative
array. It is always safe for user code to read these parameters. Some
parameters may also be set; these are noted explicitly. Others are
included in this group as they are set by the function system for the
users benefit, i.e. setting them is typically not useful but is benign.</p>
<p>For example, <code>local TCP_SILENT=1</code> specifies that data read during the
function call will not be printed to standard output, regardless of the
setting outside the function. Likewise, <code>local TCP_SESS=``sess</code> sets a
session for the duration of a function, and <code>local TCP_PROMPT=</code>
specifies that no prompt is used for input during the function.</p>
<p><span id="index-tcp_005fexpect_005flines"></span></p>
<p><code>tcp_expect_lines</code></p>
<p>Array. The set of lines read during the last call to <code>tcp_expect</code>,
including the last (<code>$TCP_LINE</code>).</p>
<p><span id="index-tcp_005ffilter"></span></p>
<p><code>tcp_filter</code></p>
<p>Array. May be set directly. A set of extended globbing patterns which,
if matched in <code>tcp_output</code>, will cause the line not to be printed to
standard output. The patterns should be defined as described for the
arguments to <code>tcp_expect</code>. Output of line to log files is not affected.</p>
<p><span id="index-TCP_005fHANDLER_005fACTIVE"></span></p>
<p><code>TCP_HANDLER_ACTIVE</code></p>
<p>Scalar. Set to 1 within <code>tcp_fd_handler</code> to indicate to functions called
recursively that they have been called during an editor session.
Otherwise unset.</p>
<p><span id="index-TCP_005fLINE"></span></p>
<p><code>TCP_LINE</code></p>
<p>The last line read by <code>tcp_read</code>, and hence also <code>tcp_expect</code>.</p>
<p><span id="index-TCP_005fLINE_005fFD"></span></p>
<p><code>TCP_LINE_FD</code></p>
<p>The file descriptor from which <code>$TCP_LINE</code> was read.
<code>${tcp_by_fd[$TCP_LINE_FD]}</code> will give the corresponding session name.</p>
<p><span id="index-tcp_005flines"></span></p>
<p><code>tcp_lines</code></p>
<p>Array. The set of lines read during the last call to <code>tcp_read</code>,
including the last (<code>$TCP_LINE</code>).</p>
<p><span id="index-TCP_005fLOG"></span></p>
<p><code>TCP_LOG</code></p>
<p>May be set directly, although it is also controlled by <code>tcp_log</code>. The
name of a file to which output from all sessions will be sent. The
output is proceeded by the usual <code>$TCP_PROMPT</code>. If it is not an absolute
path name, it will follow the users current directory.</p>
<p><span id="index-TCP_005fLOG_005fSESS"></span></p>
<p><code>TCP_LOG_SESS</code></p>
<p>May be set directly, although it is also controlled by <code>tcp_log</code>. The
prefix for a set of files to which output from each session separately
will be sent; the full filename is <code>${TCP_LOG_SESS}.``sess</code>. Output to
each file is raw; no prompt is added. If it is not an absolute path
name, it will follow the users current directory.</p>
<p><span id="index-tcp_005fno_005fspam_005flist"></span></p>
<p><code>tcp_no_spam_list</code></p>
<p>Array. May be set directly. See <code>tcp_spam</code> for how this is used.</p>
<p><span id="index-TCP_005fOUTPUT"></span></p>
<p><code>TCP_OUTPUT</code></p>
<p>May be set directly. If a non-empty string, any data sent to a session
by <code>tcp_send</code> will be logged. This parameter gives the prompt to be used
in a file specified by <code>$TCP_LOG</code> but not in a file generated from
<code>$TCP_LOG_SESS</code>. The prompt string has the same format as <code>TCP_PROMPT</code>
and the same rules for its use apply.</p>
<p><span id="index-TCP_005fPROMPT"></span></p>
<p><code>TCP_PROMPT</code></p>
<p>May be set directly. Used as the prefix for data read by <code>tcp_read</code>
which is printed to standard output or to the log file given by
<code>$TCP_LOG</code>, if any. Any <code>%s</code>, <code>%f</code> or <code>%%</code> occurring in the string
will be replaced by the name of the session, the sessions underlying
file descriptor, or a single <code>%</code>, respectively. The expression <code>%c</code>
expands to 1 if the session being read is the current session, else 0;
this is most useful in ternary expressions such as <code>%(c.-.+)</code> which
outputs <code>+</code> if the session is the current one, else <code>-</code>.</p>
<p>If the prompt starts with <code>%P</code>, this is stripped and the complete result
of the previous stage is passed through standard prompt <code>%</code>-style
formatting before being output.</p>
<p><span id="index-TCP_005fREAD_005fDEBUG"></span></p>
<p><code>TCP_READ_DEBUG</code></p>
<p>May be set directly. If this has non-zero length, <code>tcp_read</code> will give
some limited diagnostics about data being read.</p>
<p><span id="index-TCP_005fSECONDS_005fSTART"></span></p>
<p><code>TCP_SECONDS_START</code></p>
<p>This value is created and initialised to zero by tcp_open.</p>
<p>The functions <code>tcp_read</code> and <code>tcp_expect</code> use the shells <code>SECONDS</code>
parameter for their own timing purposes. If that parameter is not of
floating point type on entry to one of the functions, it will create a
local parameter <code>SECONDS</code> which is floating point and set the parameter
<code>TCP_SECONDS_START</code> to the previous value of <code>$SECONDS</code>. If the
parameter is already floating point, it is used without a local copy
being created and <code>TCP_SECONDS_START</code> is not set. As the global value is
zero, the shell elapsed time is guaranteed to be the sum of <code>$SECONDS</code>
and <code>$TCP_SECONDS_START</code>.</p>
<p>This can be avoided by setting <code>SECONDS</code> globally to a floating point
value using <code>typeset -F SECONDS</code>; then the TCP functions will never
make a local copy and never set <code>TCP_SECONDS_START</code> to a non-zero value.</p>
<p><span id="index-TCP_005fSESS"></span></p>
<p><code>TCP_SESS</code></p>
<p>May be set directly. The current session; must refer to one of the
sessions established by <code>tcp_open</code>.</p>
<p><span id="index-TCP_005fSILENT"></span></p>
<p><code>TCP_SILENT</code></p>
<p>May be set directly, although it is also controlled by <code>tcp_log</code>. If of
non-zero length, data read by <code>tcp_read</code> will not be written to standard
output, though may still be written to a log file.</p>
<p><span id="index-tcp_005fspam_005flist"></span></p>
<p><code>tcp_spam_list</code></p>
<p>Array. May be set directly. See the description of the function
<code>tcp_spam</code> for how this is used.</p>
<p><span id="index-TCP_005fTALK_005fESCAPE"></span></p>
<p><code>TCP_TALK_ESCAPE</code></p>
<p>May be set directly. See the description of the function <code>tcp_talk</code> for
how this is used.</p>
<p><span id="index-TCP_005fTIMEOUT"></span></p>
<p><code>TCP_TIMEOUT</code></p>
<p>May be set directly. Currently this is only used by the function
<code>tcp_command</code>, see above.</p>
<hr />
<p><span id="TCP-User_002ddefined-Parameters"></span></p>
<h2 id="246-tcp-user-defined-parameters"><a class="header" href="#246-tcp-user-defined-parameters">24.6 TCP User-defined Parameters</a></h2>
<p>The following parameters are not set by the function system, but have a
special effect if set by the user.</p>
<p><span id="index-tcp_005fon_005fread"></span></p>
<p><code>tcp_on_read</code></p>
<p>This should be an associative array; if it is not, the behaviour is
undefined. Each key is the name of a shell function or other command,
and the corresponding value is a shell pattern (using <code>EXTENDED_GLOB</code>).
Every line read from a TCP session directly or indirectly using
<code>tcp_read</code> (which includes lines read by <code>tcp_expect</code>) is compared
against the pattern. If the line matches, the command given in the key
is called with two arguments: the name of the session from which the
line was read, and the line itself.</p>
<p>If any function called to handle a line returns a non-zero status, the
line is not output. Thus a <code>tcp_on_read</code> handler containing only the
instruction <code>return 1</code> can be used to suppress output of particular
lines (see, however, <code>tcp_filter</code> above). However, the line is still
stored in <code>TCP_LINE</code> and <code>tcp_lines</code>; this occurs after all
<code>tcp_on_read</code> processing.</p>
<hr />
<p><span id="TCP-Utility-Parameters"></span></p>
<h2 id="247-tcp-utility-parameters"><a class="header" href="#247-tcp-utility-parameters">24.7 TCP Utility Parameters</a></h2>
<p>These parameters are controlled by the function system; they may be read
directly, but should not usually be set by user code.</p>
<p><span id="index-tcp_005faliases"></span></p>
<p><code>tcp_aliases</code></p>
<p>Associative array. The keys are the names of sessions established with
<code>tcp_open</code>; each value is a space-separated list of aliases which refer
to that session.</p>
<p><span id="index-tcp_005fby_005ffd"></span></p>
<p><code>tcp_by_fd</code></p>
<p>Associative array. The keys are session file descriptors; each value is
the name of that session.</p>
<p><span id="index-tcp_005fby_005fname"></span></p>
<p><code>tcp_by_name</code></p>
<p>Associative array. The keys are the names of sessions; each value is the
file descriptor associated with that session.</p>
<hr />
<p><span id="TCP-Examples"></span> <span id="TCP-Examples-1"></span></p>
<h2 id="248-tcp-examples"><a class="header" href="#248-tcp-examples">24.8 TCP Examples</a></h2>
<p>Here is a trivial example using a remote calculator.</p>
<p>To create a calculator server on port 7337 (see the <code>dc</code> manual page for
quite how infuriating the underlying command is):</p>
<div class="example">
<pre><code class="language-example">tcp_proxy 7337 dc
</code></pre>
</div>
<p>To connect to this from the same host with a session also named <code>dc</code>:</p>
<div class="example">
<pre><code class="language-example">tcp_open localhost 7337 dc
</code></pre>
</div>
<p>To send a command to the remote session and wait a short while for
output (assuming <code>dc</code> is the current session):</p>
<div class="example">
<pre><code class="language-example">tcp_command 2 4 + p
</code></pre>
</div>
<p>To close the session:</p>
<div class="example">
<pre><code class="language-example">tcp_close
</code></pre>
</div>
<p>The <code>tcp_proxy</code> needs to be killed to be stopped. Note this will not
usually kill any connections which have already been accepted, and also
that the port is not immediately available for reuse.</p>
<p>The following chunk of code puts a list of sessions into an xterm
header, with the current session followed by a star.</p>
<div class="example">
<pre><code class="language-example">print -n &quot;\033]2;TCP:&quot; ${(k)tcp_by_name:/$TCP_SESS/$TCP_SESS\*} &quot;\a&quot;
</code></pre>
</div>
<hr />
<p><span id="TCP-Bugs"></span> <span id="TCP-Bugs-1"></span></p>
<h2 id="249-tcp-bugs"><a class="header" href="#249-tcp-bugs">24.9 TCP Bugs</a></h2>
<p>The function <code>tcp_read</code> uses the shells normal <code>read</code> builtin. As this
reads a complete line at once, data arriving without a terminating
newline can cause the function to block indefinitely.</p>
<p>Though the function suite works well for interactive use and for data
arriving in small amounts, the performance when large amounts of data
are being exchanged is likely to be extremely poor.</p>
<hr />
<p>This document was generated on <em>February 15, 2020</em> using
<a href="http://www.nongnu.org/texi2html/"><em>texi2html 5.0</em></a>.<br />
Zsh version 5.8, released on February 14, 2020.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="Calendar-Function-System.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="Zftp-Function-System.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="Calendar-Function-System.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="Zftp-Function-System.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>
<!-- Livereload script (if served using the cli tool) -->
<script type="text/javascript">
var socket = new WebSocket("ws://localhost:3000/__livereload");
socket.onmessage = function (event) {
if (event.data === "reload") {
socket.close();
location.reload();
}
};
window.onbeforeunload = function() {
socket.close();
}
</script>
<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>

View File

@ -0,0 +1,292 @@
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>The Z Shell Manual - Zsh Manual</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 -->
</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 "><a href="The-Z-Shell-Manual.html" class="active"><strong aria-hidden="true">1.</strong> The Z Shell Manual</a></li><li class="chapter-item expanded "><a href="Introduction.html"><strong aria-hidden="true">2.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="Roadmap.html"><strong aria-hidden="true">3.</strong> Roadmap</a></li><li class="chapter-item expanded "><a href="Invocation.html"><strong aria-hidden="true">4.</strong> Invocation</a></li><li class="chapter-item expanded "><a href="Files.html"><strong aria-hidden="true">5.</strong> Files</a></li><li class="chapter-item expanded "><a href="Shell-Grammar.html"><strong aria-hidden="true">6.</strong> Shell Grammar</a></li><li class="chapter-item expanded "><a href="Redirection.html"><strong aria-hidden="true">7.</strong> Redirection</a></li><li class="chapter-item expanded "><a href="Command-Execution.html"><strong aria-hidden="true">8.</strong> Command Execution</a></li><li class="chapter-item expanded "><a href="Functions.html"><strong aria-hidden="true">9.</strong> Functions</a></li><li class="chapter-item expanded "><a href="Jobs-_0026-Signals.html"><strong aria-hidden="true">10.</strong> Jobs &amp; Signals</a></li><li class="chapter-item expanded "><a href="Arithmetic-Evaluation.html"><strong aria-hidden="true">11.</strong> Arithmetic Evaluation</a></li><li class="chapter-item expanded "><a href="Conditional-Expressions.html"><strong aria-hidden="true">12.</strong> Conditional Expressions</a></li><li class="chapter-item expanded "><a href="Prompt-Expansion.html"><strong aria-hidden="true">13.</strong> Prompt Expansion</a></li><li class="chapter-item expanded "><a href="Expansion.html"><strong aria-hidden="true">14.</strong> Expansion</a></li><li class="chapter-item expanded "><a href="Parameters.html"><strong aria-hidden="true">15.</strong> Parameters</a></li><li class="chapter-item expanded "><a href="Options.html"><strong aria-hidden="true">16.</strong> Options</a></li><li class="chapter-item expanded "><a href="Shell-Builtin-Commands.html"><strong aria-hidden="true">17.</strong> Shell Builtin Commands</a></li><li class="chapter-item expanded "><a href="Zsh-Line-Editor.html"><strong aria-hidden="true">18.</strong> Zsh Line Editor</a></li><li class="chapter-item expanded "><a href="Completion-Widgets.html"><strong aria-hidden="true">19.</strong> Completion Widgets</a></li><li class="chapter-item expanded "><a href="Completion-System.html"><strong aria-hidden="true">20.</strong> Completion System</a></li><li class="chapter-item expanded "><a href="Completion-Using-compctl.html"><strong aria-hidden="true">21.</strong> Completion Using compctl</a></li><li class="chapter-item expanded "><a href="Zsh-Modules.html"><strong aria-hidden="true">22.</strong> Zsh Modules</a></li><li class="chapter-item expanded "><a href="Calendar-Function-System.html"><strong aria-hidden="true">23.</strong> Calendar Function System</a></li><li class="chapter-item expanded "><a href="TCP-Function-System.html"><strong aria-hidden="true">24.</strong> TCP Function System</a></li><li class="chapter-item expanded "><a href="Zftp-Function-System.html"><strong aria-hidden="true">25.</strong> Zftp Function System</a></li><li class="chapter-item expanded "><a href="User-Contributions.html"><strong aria-hidden="true">26.</strong> User Contributions</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>
</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 Manual</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" name="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="#1-the-z-shell-manual">1 The Z Shell Manual</a>
<ul>
<li><a href="#11-producing-documentation-from-zshtexi">1.1 Producing documentation from zsh.texi</a></li>
</ul>
</li>
</ul>
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<p><span id="The-Z-Shell-Manual"></span>
<span id="The-Z-Shell-Manual-1"></span></p>
<h1 id="1-the-z-shell-manual"><a class="header" href="#1-the-z-shell-manual">1 The Z Shell Manual</a></h1>
<p>This document has been produced from the texinfo file <code>zsh.texi</code>,
included in the <code>Doc</code> sub-directory of the Zsh distribution.</p>
<hr />
<p><span id="Producing-documentation-from-zsh_002etexi"></span></p>
<h2 id="11-producing-documentation-from-zshtexi"><a class="header" href="#11-producing-documentation-from-zshtexi">1.1 Producing documentation from zsh.texi</a></h2>
<p>The texinfo source may be converted into several formats:</p>
<ul>
<li>
<p>The Info manual<br />
The Info format allows searching for topics, commands, functions,
etc. from the many Indices. The command <code>makeinfo zsh.texi</code> is
used to produce the Info documentation.</p>
</li>
<li>
<p>The printed manual<br />
The command <code>texi2dvi zsh.texi</code> will output <code>zsh.dvi</code> which can
then be processed with dvips and optionally gs (Ghostscript) to
produce a nicely formatted printed manual.</p>
</li>
<li>
<p>The HTML manual<br />
An HTML version of this manual is available at the Zsh web site via:</p>
<p><code>http://zsh.sourceforge.net/Doc/</code>.</p>
<p>(The HTML version is produced with texi2html, which may be obtained
from <code>http://www.nongnu.org/texi2html/</code>. The command is <code>texi2html output . ifinfo split=chapter node-files zsh.texi</code>. If
necessary, upgrade to version 1.78 of texi2html.)</p>
</li>
</ul>
<p>For those who do not have the necessary tools to process texinfo,
precompiled documentation (PostScript, dvi, PDF, info and HTML formats)
is available from the zsh archive site or its mirrors, in the file
<code>zsh-doc.tar.gz</code>. (See <a href="Introduction.html#Availability">Availability</a>
for a list of sites.)</p>
<hr />
<p>This document was generated on <em>February 15, 2020</em> using
<a href="http://www.nongnu.org/texi2html/"><em>texi2html 5.0</em></a>.<br />
Zsh version 5.8, released on February 14, 2020.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="next" href="Introduction.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="next" href="Introduction.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>
<!-- Livereload script (if served using the cli tool) -->
<script type="text/javascript">
var socket = new WebSocket("ws://localhost:3000/__livereload");
socket.onmessage = function (event) {
if (event.data === "reload") {
socket.close();
location.reload();
}
};
window.onbeforeunload = function() {
socket.close();
}
</script>
<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>

5273
book/User-Contributions.html Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,853 @@
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Zftp Function System - Zsh Manual</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 -->
</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 "><a href="The-Z-Shell-Manual.html"><strong aria-hidden="true">1.</strong> The Z Shell Manual</a></li><li class="chapter-item expanded "><a href="Introduction.html"><strong aria-hidden="true">2.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="Roadmap.html"><strong aria-hidden="true">3.</strong> Roadmap</a></li><li class="chapter-item expanded "><a href="Invocation.html"><strong aria-hidden="true">4.</strong> Invocation</a></li><li class="chapter-item expanded "><a href="Files.html"><strong aria-hidden="true">5.</strong> Files</a></li><li class="chapter-item expanded "><a href="Shell-Grammar.html"><strong aria-hidden="true">6.</strong> Shell Grammar</a></li><li class="chapter-item expanded "><a href="Redirection.html"><strong aria-hidden="true">7.</strong> Redirection</a></li><li class="chapter-item expanded "><a href="Command-Execution.html"><strong aria-hidden="true">8.</strong> Command Execution</a></li><li class="chapter-item expanded "><a href="Functions.html"><strong aria-hidden="true">9.</strong> Functions</a></li><li class="chapter-item expanded "><a href="Jobs-_0026-Signals.html"><strong aria-hidden="true">10.</strong> Jobs &amp; Signals</a></li><li class="chapter-item expanded "><a href="Arithmetic-Evaluation.html"><strong aria-hidden="true">11.</strong> Arithmetic Evaluation</a></li><li class="chapter-item expanded "><a href="Conditional-Expressions.html"><strong aria-hidden="true">12.</strong> Conditional Expressions</a></li><li class="chapter-item expanded "><a href="Prompt-Expansion.html"><strong aria-hidden="true">13.</strong> Prompt Expansion</a></li><li class="chapter-item expanded "><a href="Expansion.html"><strong aria-hidden="true">14.</strong> Expansion</a></li><li class="chapter-item expanded "><a href="Parameters.html"><strong aria-hidden="true">15.</strong> Parameters</a></li><li class="chapter-item expanded "><a href="Options.html"><strong aria-hidden="true">16.</strong> Options</a></li><li class="chapter-item expanded "><a href="Shell-Builtin-Commands.html"><strong aria-hidden="true">17.</strong> Shell Builtin Commands</a></li><li class="chapter-item expanded "><a href="Zsh-Line-Editor.html"><strong aria-hidden="true">18.</strong> Zsh Line Editor</a></li><li class="chapter-item expanded "><a href="Completion-Widgets.html"><strong aria-hidden="true">19.</strong> Completion Widgets</a></li><li class="chapter-item expanded "><a href="Completion-System.html"><strong aria-hidden="true">20.</strong> Completion System</a></li><li class="chapter-item expanded "><a href="Completion-Using-compctl.html"><strong aria-hidden="true">21.</strong> Completion Using compctl</a></li><li class="chapter-item expanded "><a href="Zsh-Modules.html"><strong aria-hidden="true">22.</strong> Zsh Modules</a></li><li class="chapter-item expanded "><a href="Calendar-Function-System.html"><strong aria-hidden="true">23.</strong> Calendar Function System</a></li><li class="chapter-item expanded "><a href="TCP-Function-System.html"><strong aria-hidden="true">24.</strong> TCP Function System</a></li><li class="chapter-item expanded "><a href="Zftp-Function-System.html" class="active"><strong aria-hidden="true">25.</strong> Zftp Function System</a></li><li class="chapter-item expanded "><a href="User-Contributions.html"><strong aria-hidden="true">26.</strong> User Contributions</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>
</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 Manual</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" name="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="#25-zftp-function-system">25 Zftp Function System</a>
<ul>
<li><a href="#251-description">25.1 Description</a></li>
<li><a href="#252-installation">25.2 Installation</a></li>
<li><a href="#253-functions">25.3 Functions</a>
<ul>
<li><a href="#2531-opening-a-connection">25.3.1 Opening a connection</a></li>
<li><a href="#2532-directory-management">25.3.2 Directory management</a></li>
<li><a href="#2533-status-commands">25.3.3 Status commands</a></li>
<li><a href="#2534-retrieving-files">25.3.4 Retrieving files</a></li>
<li><a href="#2535-sending-files">25.3.5 Sending files</a></li>
<li><a href="#2536-closing-the-connection">25.3.6 Closing the connection</a></li>
<li><a href="#2537-session-management">25.3.7 Session management</a></li>
<li><a href="#2538-bookmarks">25.3.8 Bookmarks</a></li>
<li><a href="#2539-other-functions">25.3.9 Other functions</a></li>
</ul>
</li>
<li><a href="#254-miscellaneous-features">25.4 Miscellaneous Features</a>
<ul>
<li><a href="#2541-configuration">25.4.1 Configuration</a></li>
<li><a href="#2542-remote-globbing">25.4.2 Remote globbing</a></li>
<li><a href="#2543-automatic-and-temporary-reopening">25.4.3 Automatic and temporary reopening</a></li>
<li><a href="#2544-completion">25.4.4 Completion</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<p><span id="Zftp-Function-System"></span>
<span id="Zftp-Function-System-1"></span></p>
<h1 id="25-zftp-function-system"><a class="header" href="#25-zftp-function-system">25 Zftp Function System</a></h1>
<p><span id="index-zftp-function-system"></span>
<span id="index-FTP_002c-functions-for-using-shell-as-client"></span></p>
<hr />
<p><span id="Description-4"></span></p>
<h2 id="251-description"><a class="header" href="#251-description">25.1 Description</a></h2>
<p>This describes the set of shell functions supplied with the source
distribution as an interface to the <code>zftp</code> builtin command, allowing you
to perform FTP operations from the shell command line or within
functions or scripts. The interface is similar to a traditional FTP
client (e.g. the <code>ftp</code> command itself, see man page ftp(1)), but as it
is entirely done within the shell all the familiar completion, editing
and globbing features, and so on, are present, and macros are
particularly simple to write as they are just ordinary shell functions.</p>
<p>The prerequisite is that the <code>zftp</code> command, as described in <a href="Zsh-Modules.html#The-zsh_002fzftp-Module">The
zsh/zftp Module</a> , must be
available in the version of <code>zsh</code> installed at your site. If the shell
is configured to load new commands at run time, it probably is: typing
<code>zmodload zsh/zftp</code> will make sure (if that runs silently, it has
worked). If this is not the case, it is possible <code>zftp</code> was linked into
the shell anyway: to test this, type <code>which zftp</code> and if <code>zftp</code> is
available you will get the message <code>zftp: shell built-in command</code>.</p>
<p>Commands given directly with <code>zftp</code> builtin may be interspersed between
the functions in this suite; in a few cases, using <code>zftp</code> directly may
cause some of the status information stored in shell parameters to
become invalid. Note in particular the description of the variables
<code>$ZFTP_TMOUT</code>, <code>$ZFTP_PREFS</code> and <code>$ZFTP_VERBOSE</code> for <code>zftp</code>.</p>
<hr />
<p><span id="Installation"></span> <span id="Installation-1"></span></p>
<h2 id="252-installation"><a class="header" href="#252-installation">25.2 Installation</a></h2>
<p>You should make sure all the functions from the <code>Functions/Zftp</code>
directory of the source distribution are available; they all begin with
the two letters <code>zf</code>. They may already have been installed on your
system; otherwise, you will need to find them and copy them. The
directory should appear as one of the elements of the <code>$fpath</code> array
(this should already be the case if they were installed), and at least
the function <code>zfinit</code> should be autoloaded; it will autoload the rest.
Finally, to initialize the use of the system you need to call the
<code>zfinit</code> function. The following code in your <code>.zshrc</code> will arrange for
this; assume the functions are stored in the directory <code>~/myfns</code>:</p>
<div class="example">
<pre><code class="language-example">fpath=(~/myfns $fpath)
autoload -U zfinit
zfinit
</code></pre>
</div>
<p>Note that <code>zfinit</code> assumes you are using the <code>zmodload</code> method to load
the <code>zftp</code> command. If it is already built into the shell, change
<code>zfinit</code> to <code>zfinit -n</code>. It is helpful (though not essential) if the
call to <code>zfinit</code> appears after any code to initialize the new completion
system, else unnecessary <code>compctl</code> commands will be given.</p>
<hr />
<p><span id="Zftp-Functions"></span> <span id="Functions-2"></span></p>
<h2 id="253-functions"><a class="header" href="#253-functions">25.3 Functions</a></h2>
<p>The sequence of operations in performing a file transfer is essentially
the same as that in a standard FTP client. Note that, due to a quirk of
the shells <code>getopts</code> builtin, for those functions that handle options
you must use <code>-``-</code> rather than <code>-</code> to ensure the remaining
arguments are treated literally (a single <code>-</code> is treated as an
argument).</p>
<hr />
<p><span id="Opening-a-connection"></span></p>
<h3 id="2531-opening-a-connection"><a class="header" href="#2531-opening-a-connection">25.3.1 Opening a connection</a></h3>
<p><span id="index-zfparams"></span></p>
<p><code>zfparams</code> [ <code>host</code> [ <code>user</code> [ <code>password</code> ... ] ] ]</p>
<p>Set or show the parameters for a future <code>zfopen</code> with no arguments. If
no arguments are given, the current parameters are displayed (the
password will be shown as a line of asterisks). If a <code>host</code> is given,
and either the <code>user</code> or <code>password</code> is not, they will be prompted for;
also, any parameter given as <code>?</code> will be prompted for, and if the
<code>?</code> is followed by a string, that will be used as the prompt. As
<code>zfopen</code> calls <code>zfparams</code> to store the parameters, this usually need not
be called directly.</p>
<p>A single argument <code>-</code> will delete the stored parameters. This will
also cause the memory of the last directory (and so on) on the other
host to be deleted.</p>
<p><span id="index-zfopen"></span></p>
<p><code>zfopen</code> [ <code>-1</code> ] [ <code>host</code> [ <code>user</code> [ <code>password</code> [ <code>account</code> ] ]
] ]</p>
<p>If <code>host</code> is present, open a connection to that host under username
<code>user</code> with password <code>password</code> (and, on the rare occasions when it is
necessary, account <code>account</code>). If a necessary parameter is missing or
given as <code>?</code> it will be prompted for. If <code>host</code> is not present, use a
previously stored set of parameters.</p>
<p>If the command was successful, and the terminal is compatible with
<code>xterm</code> or is <code>sun-cmd</code>, a summary will appear in the title bar, giving
the local <code>host:directory</code> and the remote <code>host:directory</code>; this is
handled by the function <code>zftp_chpwd</code>, described below.</p>
<p>Normally, the <code>host</code>, <code>user</code> and <code>password</code> are internally recorded for
later re-opening, either by a <code>zfopen</code> with no arguments, or
automatically (see below). With the option <code>-1</code>, no information is
stored. Also, if an open command with arguments failed, the parameters
will not be retained (and any previous parameters will also be deleted).
A <code>zfopen</code> on its own, or a <code>zfopen -1</code>, never alters the stored
parameters.</p>
<p>Both <code>zfopen</code> and <code>zfanon</code> (but not <code>zfparams</code>) understand URLs of the
form <code>ftp://``host</code>/<code>path...</code> as meaning to connect to the <code>host</code>, then
change directory to <code>path</code> (which must be a directory, not a file). The
<code>ftp://</code> can be omitted; the trailing <code>/</code> is enough to trigger
recognition of the <code>path</code>. Note prefixes other than <code>ftp:</code> are not
recognized, and that all characters after the first slash beyond <code>host</code>
are significant in <code>path</code>.</p>
<p><span id="index-zfanon"></span></p>
<p><code>zfanon</code> [ <code>-1</code> ] <code>host</code></p>
<p>Open a connection <code>host</code> for anonymous FTP. The username used is
<code>anonymous</code>. The password (which will be reported the first time) is
generated as <code>user``@``host</code>; this is then stored in the shell parameter
<code>$EMAIL_ADDR</code> which can alternatively be set manually to a</p>
<hr />
<p><span id="Directory-management"></span></p>
<h3 id="2532-directory-management"><a class="header" href="#2532-directory-management">25.3.2 Directory management</a></h3>
<p><span id="index-zfcd"></span></p>
<p><code>zfcd</code> [ <code>dir</code> ]</p>
<p><code>zfcd -</code></p>
<p><code>zfcd</code> <code>old</code> <code>new</code></p>
<p>Change the current directory on the remote server: this is implemented
to have many of the features of the shell builtin <code>cd</code>.</p>
<p>In the first form with <code>dir</code> present, change to the directory <code>dir</code>. The
command <code>zfcd ..</code> is treated specially, so is guaranteed to work on
non-UNIX servers (note this is handled internally by <code>zftp</code>). If <code>dir</code>
is omitted, has the effect of <code>zfcd ~</code>.</p>
<p>The second form changes to the directory previously current.</p>
<p>The third form attempts to change the current directory by replacing the
first occurrence of the string <code>old</code> with the string <code>new</code> in the
current directory.</p>
<p>Note that in this command, and indeed anywhere a remote filename is
expected, the string which on the local host corresponds to <code>~</code> is
converted back to a <code>~</code> before being passed to the remote machine.
This is convenient because of the way expansion is performed on the
command line before <code>zfcd</code> receives a string. For example, suppose the
command is <code>zfcd ~/foo</code>. The shell will expand this to a full path
such as <code>zfcd /home/user2/pws/foo</code>. At this stage, <code>zfcd</code> recognises
the initial path as corresponding to <code>~</code> and will send the directory
to the remote host as <code>~/foo</code>, so that the <code>~</code> will be expanded by the
server to the correct remote host directory. Other named directories of
the form <code>~name</code> are not treated in this fashion.</p>
<p><span id="index-zfhere"></span></p>
<p><code>zfhere</code></p>
<p>Change directory on the remote server to the one corresponding to the
current local directory, with special handling of <code>~</code> as in <code>zfcd</code>.
For example, if the current local directory is <code>~/foo/bar</code>, then
<code>zfhere</code> performs the effect of <code>zfcd ~/foo/bar</code>.</p>
<p><span id="index-zfdir"></span></p>
<p><code>zfdir</code> [ <code>-rfd</code> ] [ <code>-</code> ] [ <code>dir-options</code> ] [ <code>dir</code> ]</p>
<p>Produce a long directory listing. The arguments <code>dir-options</code> and <code>dir</code>
are passed directly to the server and their effect is implementation
dependent, but specifying a particular remote directory <code>dir</code> is usually
possible. The output is passed through a pager given by the environment
variable <code>$PAGER</code>, or <code>more</code> if that is not set.</p>
<p>The directory is usually cached for re-use. In fact, two caches are
maintained. One is for use when there is no <code>dir-options</code> or <code>dir</code>, i.e.
a full listing of the current remote directory; it is flushed when the
current remote directory changes. The other is kept for repeated use of
<code>zfdir</code> with the same arguments; for example, repeated use of <code>zfdir /pub/gnu</code> will only require the directory to be retrieved on the first
call. Alternatively, this cache can be re-viewed with the <code>-r</code> option.
As relative directories will confuse <code>zfdir</code>, the <code>-f</code> option can be
used to force the cache to be flushed before the directory is listed.
The option <code>-d</code> will delete both caches without showing a directory
listing; it will also delete the cache of file names in the current
remote directory, if any.</p>
<p><span id="index-zfls"></span></p>
<p><code>zfls</code> [ <code>ls-options</code> ] [ <code>dir</code> ]</p>
<p>List files on the remote server. With no arguments, this will produce a
simple list of file names for the current remote directory. Any
arguments are passed directly to the server. No pager and no caching is
used.</p>
<hr />
<p><span id="Status-commands"></span></p>
<h3 id="2533-status-commands"><a class="header" href="#2533-status-commands">25.3.3 Status commands</a></h3>
<p><span id="index-zftype"></span></p>
<p><code>zftype</code> [ <code>type</code> ]</p>
<p>With no arguments, show the type of data to be transferred, usually
ASCII or binary. With an argument, change the type: the types <code>A</code> or
<code>ASCII</code> for ASCII data and <code>B</code> or <code>BINARY</code>, <code>I</code> or <code>IMAGE</code>
for binary data are understood case-insensitively.</p>
<p><span id="index-zfstat"></span></p>
<p><code>zfstat</code> [ <code>-v</code> ]</p>
<p>Show the status of the current or last connection, as well as the status
of some of <code>zftp</code>s status variables. With the <code>-v</code> option, a more
verbose listing is produced by querying the server for its version of
events, too.</p>
<hr />
<p><span id="Retrieving-files"></span></p>
<h3 id="2534-retrieving-files"><a class="header" href="#2534-retrieving-files">25.3.4 Retrieving files</a></h3>
<p>The commands for retrieving files all take at least two options. <code>-G</code>
suppresses remote filename expansion which would otherwise be performed
(see below for a more detailed description of that). <code>-t</code> attempts to
set the modification time of the local file to that of the remote file:
see the description of the function <code>zfrtime</code> below for more
information.</p>
<p><span id="index-zfget"></span></p>
<p><code>zfget</code> [ <code>-Gtc</code> ] <code>file1</code> ...</p>
<p>Retrieve all the listed files <code>file1</code> ... one at a time from the remote
server. If a file contains a <code>/</code>, the full name is passed to the
remote server, but the file is stored locally under the name given by
the part after the final <code>/</code>. The option <code>-c</code> (cat) forces all files
to be sent as a single stream to standard output; in this case the <code>-t</code>
option has no effect.</p>
<p><span id="index-zfuget"></span></p>
<p><code>zfuget</code> [ <code>-Gvst</code> ] <code>file1</code> ...</p>
<p>As <code>zfget</code>, but only retrieve files where the version on the remote
server is newer (has a later modification time), or where the local file
does not exist. If the remote file is older but the files have different
sizes, or if the sizes are the same but the remote file is newer, the
user will usually be queried. With the option <code>-s</code>, the command runs
silently and will always retrieve the file in either of those two cases.
With the option <code>-v</code>, the command prints more information about the
files while it is working out whether or not to transfer them.</p>
<p><span id="index-zfcget"></span></p>
<p><code>zfcget</code> [ <code>-Gt</code> ] <code>file1</code> ...</p>
<p>As <code>zfget</code>, but if any of the local files exists, and is shorter than
the corresponding remote file, the command assumes that it is the result
of a partially completed transfer and attempts to transfer the rest of
the file. This is useful on a poor connection which keeps failing.</p>
<p>Note that this requires a commonly implemented, but non-standard,
version of the FTP protocol, so is not guaranteed to work on all
servers.</p>
<p><span id="index-zfgcp"></span></p>
<p><code>zfgcp</code> [ <code>-Gt</code> ] <code>remote-file</code> <code>local-file</code></p>
<p><code>zfgcp</code> [ <code>-Gt</code> ] <code>rfile1</code> ... <code>ldir</code></p>
<p>This retrieves files from the remote server with arguments behaving
similarly to the <code>cp</code> command.</p>
<p>In the first form, copy <code>remote-file</code> from the server to the local file
<code>local-file</code>.</p>
<p>In the second form, copy all the remote files <code>rfile1</code> ... into the
local directory <code>ldir</code> retaining the same basenames. This assumes UNIX
directory semantics.</p>
<hr />
<p><span id="Sending-files"></span></p>
<h3 id="2535-sending-files"><a class="header" href="#2535-sending-files">25.3.5 Sending files</a></h3>
<p><span id="index-zfput"></span></p>
<p><code>zfput</code> [ <code>-r</code> ] <code>file1</code> ...</p>
<p>Send all the <code>file1</code> ... given separately to the remote server. If a
filename contains a <code>/</code>, the full filename is used locally to find the
file, but only the basename is used for the remote file name.</p>
<p>With the option <code>-r</code>, if any of the <code>files</code> are directories they are
sent recursively with all their subdirectories, including files
beginning with <code>.</code>. This requires that the remote machine understand
UNIX file semantics, since <code>/</code> is used as a directory separator.</p>
<p><span id="index-zfuput"></span></p>
<p><code>zfuput</code> [ <code>-vs</code> ] <code>file1</code> ...</p>
<p>As <code>zfput</code>, but only send files which are newer than their remote
equivalents, or if the remote file does not exist. The logic is the same
as for <code>zfuget</code>, but reversed between local and remote files.</p>
<p><span id="index-zfcput"></span></p>
<p><code>zfcput</code> <code>file1</code> ...</p>
<p>As <code>zfput</code>, but if any remote file already exists and is shorter than
the local equivalent, assume it is the result of an incomplete transfer
and send the rest of the file to append to the existing part. As the FTP
append command is part of the standard set, this is in principle more
likely to work than <code>zfcget</code>.</p>
<p><span id="index-zfpcp"></span></p>
<p><code>zfpcp</code> <code>local-file</code> <code>remote-file</code></p>
<p><code>zfpcp</code> <code>lfile1</code> ... <code>rdir</code></p>
<p>This sends files to the remote server with arguments behaving similarly
to the <code>cp</code> command.</p>
<p>With two arguments, copy <code>local-file</code> to the server as <code>remote-file</code>.</p>
<p>With more than two arguments, copy all the local files <code>lfile1</code> ... into
the existing remote directory <code>rdir</code> retaining the same basenames. This
assumes UNIX directory semantics.</p>
<p>A problem arises if you attempt to use <code>zfpcp</code> <code>lfile1</code> <code>rdir</code>, i.e. the
second form of copying but with two arguments, as the command has no
simple way of knowing if <code>rdir</code> corresponds to a directory or a
filename. It attempts to resolve this in various ways. First, if the
<code>rdir</code> argument is <code>.</code> or <code>..</code> or ends in a slash, it is assumed to
be a directory. Secondly, if the operation of copying to a remote file
in the first form failed, and the remote server sends back the expected
failure code 553 and a reply including the string <code>Is a directory</code>,
then <code>zfpcp</code> will retry using the second form.</p>
<hr />
<p><span id="Closing-the-connection"></span></p>
<h3 id="2536-closing-the-connection"><a class="header" href="#2536-closing-the-connection">25.3.6 Closing the connection</a></h3>
<p><span id="index-zfclose"></span></p>
<p><code>zfclose</code></p>
<p>Close the connection.</p>
<hr />
<p><span id="Session-management"></span></p>
<h3 id="2537-session-management"><a class="header" href="#2537-session-management">25.3.7 Session management</a></h3>
<p><span id="index-zfsession"></span></p>
<p><code>zfsession</code> [ <code>-lvod</code> ] [ <code>sessname</code> ]</p>
<p>Allows you to manage multiple FTP sessions at once. By default,
connections take place in a session called <code>default</code>; by giving the
command <code>zfsession</code> <code>sessname</code> you can change to a new or existing
session with a name of your choice. The new session remembers its own
connection, as well as associated shell parameters, and also the
host/user parameters set by <code>zfparams</code>. Hence you can have different
sessions set up to connect to different hosts, each remembering the
appropriate host, user and password.</p>
<p>With no arguments, <code>zfsession</code> prints the name of the current session;
with the option <code>-l</code> it lists all sessions which currently exist, and
with the option <code>-v</code> it gives a verbose list showing the host and
directory for each session, where the current session is marked with an
asterisk. With <code>-o</code>, it will switch to the most recent previous session.</p>
<p>With <code>-d</code>, the given session (or else the current one) is removed;
everything to do with it is completely forgotten. If it was the only
session, a new session called <code>default</code> is created and made current.
It is safest not to delete sessions while background commands using
<code>zftp</code> are active.</p>
<p><span id="index-zftransfer"></span></p>
<p><code>zftransfer</code> <code>sess1``:``file1</code> <code>sess2``:``file2</code></p>
<p>Transfer files between two sessions; no local copy is made. The file is
read from the session <code>sess1</code> as <code>file1</code> and written to session <code>sess2</code>
as file <code>file2</code>; <code>file1</code> and <code>file2</code> may be relative to the current
directories of the session. Either <code>sess1</code> or <code>sess2</code> may be omitted
(though the colon should be retained if there is a possibility of a
colon appearing in the file name) and defaults to the current session;
<code>file2</code> may be omitted or may end with a slash, in which case the
basename of <code>file1</code> will be added. The sessions <code>sess1</code> and <code>sess2</code> must
be distinct.</p>
<p>The operation is performed using pipes, so it is required that the
connections still be valid in a subshell, which is not the case under
versions of some operating systems, presumably due to a system bug.</p>
<hr />
<p><span id="Bookmarks"></span></p>
<h3 id="2538-bookmarks"><a class="header" href="#2538-bookmarks">25.3.8 Bookmarks</a></h3>
<p>The two functions <code>zfmark</code> and <code>zfgoto</code> allow you to bookmark the
present location (host, user and directory) of the current FTP
connection for later use. The file to be used for storing and retrieving
bookmarks is given by the parameter <code>$ZFTP_BMFILE</code>; if not set when one
of the two functions is called, it will be set to the file <code>.zfbkmarks</code>
in the directory where your zsh startup files live (usually <code>~</code>).</p>
<p><span id="index-zfmark"></span></p>
<p><code>zfmark</code> [ <code>bookmark</code> ]</p>
<p>If given an argument, mark the current host, user and directory under
the name <code>bookmark</code> for later use by <code>zfgoto</code>. If there is no connection
open, use the values for the last connection immediately before it was
closed; it is an error if there was none. Any existing bookmark under
the same name will be silently replaced.</p>
<p>If not given an argument, list the existing bookmarks and the points to
which they refer in the form <code>user``@``host``:``directory</code>; this is the
format in which they are stored, and the file may be edited directly.</p>
<p><span id="index-zfgoto"></span></p>
<p><code>zfgoto</code> [ <code>-n</code> ] <code>bookmark</code></p>
<p>Return to the location given by <code>bookmark</code>, as previously set by
<code>zfmark</code>. If the location has user <code>ftp</code> or <code>anonymous</code>, open the
connection with <code>zfanon</code>, so that no password is required. If the user
and host parameters match those stored for the current session, if any,
those will be used, and again no password is required. Otherwise a
password will be prompted for.</p>
<p>With the option <code>-n</code>, the bookmark is taken to be a nickname stored by
the <code>ncftp</code> program in its bookmark file, which is assumed to be
<code>~/.ncftp/bookmarks</code>. The function works identically in other ways. Note
that there is no mechanism for adding or modifying <code>ncftp</code> bookmarks
from the zftp functions.</p>
<hr />
<p><span id="Other-functions"></span></p>
<h3 id="2539-other-functions"><a class="header" href="#2539-other-functions">25.3.9 Other functions</a></h3>
<p>Mostly, these functions will not be called directly (apart from
<code>zfinit</code>), but are described here for completeness. You may wish to
alter <code>zftp_chpwd</code> and <code>zftp_progress</code>, in particular.</p>
<p><span id="index-zfinit"></span></p>
<p><code>zfinit</code> [ <code>-n</code> ]</p>
<p>As described above, this is used to initialize the zftp function system.
The <code>-n</code> option should be used if the zftp command is already built into
the shell.</p>
<p><span id="index-zfautocheck"></span></p>
<p><code>zfautocheck</code> [ <code>-dn</code> ]</p>
<p>This function is called to implement automatic reopening behaviour, as
described in more detail below. The options must appear in the first
argument; <code>-n</code> prevents the command from changing to the old directory,
while <code>-d</code> prevents it from setting the variable <code>do_close</code>, which it
otherwise does as a flag for automatically closing the connection after
a transfer. The host and directory for the last session are stored in
the variable <code>$zflastsession</code>, but the internal host/user/password
parameters must also be correctly set.</p>
<p><span id="index-zfcd_005fmatch"></span></p>
<p><code>zfcd_match prefix suffix</code></p>
<p>This performs matching for completion of remote directory names. If the
remote server is UNIX, it will attempt to persuade the server to list
the remote directory with subdirectories marked, which usually works but
is not guaranteed. On other hosts it simply calls <code>zfget_match</code> and
hence completes all files, not just directories. On some systems,
directories may not even look like filenames.</p>
<p><span id="index-zfget_005fmatch"></span></p>
<p><code>zfget_match prefix suffix</code></p>
<p>This performs matching for completion of remote filenames. It caches
files for the current directory (only) in the shell parameter
<code>$zftp_fcache</code>. It is in the form to be called by the <code>-K</code> option of
<code>compctl</code>, but also works when called from a widget-style completion
function with <code>prefix</code> and <code>suffix</code> set appropriately.</p>
<p><span id="index-zfrglob"></span></p>
<p><code>zfrglob varname</code></p>
<p>Perform remote globbing, as describes in more detail below. <code>varname</code> is
the name of a variable containing the pattern to be expanded; if there
were any matches, the same variable will be set to the expanded set of
filenames on return.</p>
<p><span id="index-zfrtime"></span></p>
<p><code>zfrtime</code> <code>lfile</code> <code>rfile</code> [ <code>time</code> ]</p>
<p>Set the local file <code>lfile</code> to have the same modification time as the
remote file <code>rfile</code>, or the explicit time <code>time</code> in FTP format
<code>CCYYMMDDhhmmSS</code> for the GMT timezone. This uses the shells
<code>zsh/datetime</code> module to perform the conversion from GMT to local time.</p>
<p><span id="index-zftp_005fchpwd_002c-supplied-version"></span></p>
<p><code>zftp_chpwd</code></p>
<p>This function is called every time a connection is opened, or closed, or
the remote directory changes. This version alters the title bar of an
<code>xterm</code>-compatible or <code>sun-cmd</code> terminal emulator to reflect the local
and remote hostnames and current directories. It works best when
combined with the function <code>chpwd</code>. In particular, a function of the
form</p>
<div class="example">
<pre><code class="language-example">chpwd() {
if [[ -n $ZFTP_USER ]]; then
zftp_chpwd
else
# usual chpwd e.g put host:directory in title bar
fi
}
</code></pre>
</div>
<p>fits in well.</p>
<p><span id="index-zftp_005fprogress_002c-supplied-version"></span></p>
<p><code>zftp_progress</code></p>
<p>This function shows the status of the transfer. It will not write
anything unless the output is going to a terminal; however, if you
transfer files in the background, you should turn off progress reports
by hand using <code>zstyle :zftp:* progress none</code>. Note also that if you
alter it, any output <em>must</em> be to standard error, as standard output may
be a file being received. The form of the progress meter, or whether it
is used at all, can be configured without altering the function, as
described in the next section.</p>
<p><span id="index-zffcache"></span></p>
<p><code>zffcache</code></p>
<p>This is used to implement caching of files in the current directory for
each session separately. It is used by <code>zfget_match</code> and <code>zfrglob</code>.</p>
<hr />
<p><span id="Miscellaneous-Features"></span>
<span id="Miscellaneous-Features-1"></span></p>
<h2 id="254-miscellaneous-features"><a class="header" href="#254-miscellaneous-features">25.4 Miscellaneous Features</a></h2>
<hr />
<p><span id="Configuration-3"></span></p>
<h3 id="2541-configuration"><a class="header" href="#2541-configuration">25.4.1 Configuration</a></h3>
<p><span id="index-zftp-function-system_002c-configuration"></span>
<span id="index-zftp-function-system_002c-styles"></span>
<span id="index-styles-in-zftp-functions"></span></p>
<p>Various styles are available using the standard shell style mechanism,
described in <a href="Zsh-Modules.html#The-zsh_002fzutil-Module">The zsh/zutil
Module</a>. Briefly, the command
<code>zstyle :zftp:*</code> <code>style</code> <code>value</code> .... defines the <code>style</code> to have
value <code>value</code>; more than one value may be given, although that is not
useful in the cases described here. These values will then be used
throughout the zftp function system. For more precise control, the first
argument, which gives a context in which the style applies, can be
modified to include a particular function, as for example
<code>:zftp:zfget</code>: the style will then have the given value only in
the <code>zfget</code> function. Values for the same style in different contexts
may be set; the most specific function will be used, where strings are
held to be more specific than patterns, and longer patterns and shorter
patterns. Note that only the top level function name, as called by the
user, is used; calling of lower level functions is transparent to the
user. Hence modifications to the title bar in <code>zftp_chpwd</code> use the
contexts <code>:zftp:zfopen</code>, <code>:zftp:zfcd</code>, etc., depending where it was
called from. The following styles are understood:</p>
<p><span id="index-progress_002c-zftp-style"></span></p>
<p><code>progress</code></p>
<p>Controls the way that <code>zftp_progress</code> reports on the progress of a
transfer. If empty, unset, or <code>none</code>, no progress report is made; if
<code>bar</code> a growing bar of inverse video is shown; if <code>percent</code> (or
any other string, though this may change in future), the percentage of
the file transferred is shown. The bar meter requires that the width of
the terminal be available via the <code>$COLUMNS</code> parameter (normally this is
set automatically). If the size of the file being transferred is not
available, <code>bar</code> and <code>percent</code> meters will simply show the number of
bytes transferred so far.</p>
<p>When <code>zfinit</code> is run, if this style is not defined for the context
<code>:zftp:*</code>, it will be set to bar.</p>
<p><span id="index-update_002c-zftp-style"></span></p>
<p><code>update</code></p>
<p>Specifies the minimum time interval between updates of the progress
meter in seconds. No update is made unless new data has been received,
so the actual time interval is limited only by <code>$ZFTP_TIMEOUT</code>.</p>
<p>As described for <code>progress</code>, <code>zfinit</code> will force this to default to 1.</p>
<p><span id="index-remote_002dglob_002c-zftp-style"></span></p>
<p><code>remote-glob</code></p>
<p>If set to <code>1</code>, <code>yes</code> or <code>true</code>, filename generation (globbing) is
performed on the remote machine instead of by zsh itself; see below.</p>
<p><span id="index-titlebar_002c-zftp-style"></span></p>
<p><code>titlebar</code></p>
<p>If set to <code>1</code>, <code>yes</code> or <code>true</code>, <code>zftp_chpwd</code> will put the remote
host and remote directory into the titlebar of terminal emulators such
as xterm or sun-cmd that allow this.</p>
<p>As described for <code>progress</code>, <code>zfinit</code> will force this to default to 1.</p>
<p><span id="index-chpwd_002c-zftp-style"></span></p>
<p><code>chpwd</code></p>
<p>If set to <code>1</code> <code>yes</code> or <code>true</code>, <code>zftp_chpwd</code> will call the function
<code>chpwd</code> when a connection is closed. This is useful if the remote host
details were put into the terminal title bar by <code>zftp_chpwd</code> and your
usual <code>chpwd</code> also modifies the title bar.</p>
<p>When <code>zfinit</code> is run, it will determine whether <code>chpwd</code> exists and if so
it will set the default value for the style to 1 if none exists already.</p>
<p>Note that there is also an associative array <code>zfconfig</code> which contains
values used by the function system. This should not be modified or
overwritten.</p>
<hr />
<p><span id="Remote-globbing"></span></p>
<h3 id="2542-remote-globbing"><a class="header" href="#2542-remote-globbing">25.4.2 Remote globbing</a></h3>
<p><span id="index-zftp-function-system_002c-remote-globbing"></span></p>
<p>The commands for retrieving files usually perform filename generation
(globbing) on their arguments; this can be turned off by passing the
option <code>-G</code> to each of the commands. Normally this operates by
retrieving a complete list of files for the directory in question, then
matching these locally against the pattern supplied. This has the
advantage that the full range of zsh patterns (respecting the setting of
the option <code>EXTENDED_GLOB</code>) can be used. However, it means that the
directory part of a filename will not be expanded and must be given
exactly. If the remote server does not support the UNIX directory
semantics, directory handling is problematic and it is recommended that
globbing only be used within the current directory. The list of files in
the current directory, if retrieved, will be cached, so that subsequent
globs in the same directory without an intervening <code>zfcd</code> are much
faster.</p>
<p>If the <code>remote-glob</code> style (see above) is set, globbing is instead
performed on the remote host: the server is asked for a list of matching
files. This is highly dependent on how the server is implemented, though
typically UNIX servers will provide support for basic glob patterns.
This may in some cases be faster, as it avoids retrieving the entire
list of directory contents.</p>
<hr />
<p><span id="Automatic-and-temporary-reopening"></span></p>
<h3 id="2543-automatic-and-temporary-reopening"><a class="header" href="#2543-automatic-and-temporary-reopening">25.4.3 Automatic and temporary reopening</a></h3>
<p><span id="index-zftp-function-system_002c-automatic-reopening"></span></p>
<p>As described for the <code>zfopen</code> command, a subsequent <code>zfopen</code> with no
parameters will reopen the connection to the last host (this includes
connections made with the <code>zfanon</code> command). Opened in this fashion, the
connection starts in the default remote directory and will remain open
until explicitly closed.</p>
<p>Automatic re-opening is also available. If a connection is not currently
open and a command requiring a connection is given, the last connection
is implicitly reopened. In this case the directory which was current
when the connection was closed again becomes the current directory
(unless, of course, the command given changes it). Automatic reopening
will also take place if the connection was close by the remote server
for whatever reason (e.g. a timeout). It is not available if the <code>-1</code>
option to <code>zfopen</code> or <code>zfanon</code> was used.</p>
<p>Furthermore, if the command issued is a file transfer, the connection
will be closed after the transfer is finished, hence providing a
one-shot mode for transfers. This does not apply to directory changing
or listing commands; for example a <code>zfdir</code> may reopen a connection but
will leave it open. Also, automatic closure will only ever happen in the
same command as automatic opening, i.e a <code>zfdir</code> directly followed by a
<code>zfget</code> will never close the connection automatically.</p>
<p>Information about the previous connection is given by the <code>zfstat</code>
function. So, for example, if that reports:</p>
<div class="example">
<pre><code class="language-example">Session: default
Not connected.
Last session: ftp.bar.com:/pub/textfiles
</code></pre>
</div>
<p>then the command <code>zfget file.txt</code> will attempt to reopen a connection to
<code>ftp.bar.com</code>, retrieve the file <code>/pub/textfiles/file.txt</code>, and
immediately close the connection again. On the other hand, <code>zfcd ..</code>
will open the connection in the directory <code>/pub</code> and leave it open.</p>
<p>Note that all the above is local to each session; if you return to a
previous session, the connection for that session is the one which will
be reopened.</p>
<hr />
<p><span id="Completion-3"></span></p>
<h3 id="2544-completion"><a class="header" href="#2544-completion">25.4.4 Completion</a></h3>
<p>Completion of local and remote files, directories, sessions and
bookmarks is supported. The older, <code>compctl</code>-style completion is defined
when <code>zfinit</code> is called; support for the new widget-based completion
system is provided in the function <code>Completion/Zsh/Command/_zftp</code>, which
should be installed with the other functions of the completion system
and hence should automatically be available.</p>
<hr />
<p>This document was generated on <em>February 15, 2020</em> using
<a href="http://www.nongnu.org/texi2html/"><em>texi2html 5.0</em></a>.<br />
Zsh version 5.8, released on February 14, 2020.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="TCP-Function-System.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="User-Contributions.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="TCP-Function-System.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="User-Contributions.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>
<!-- Livereload script (if served using the cli tool) -->
<script type="text/javascript">
var socket = new WebSocket("ws://localhost:3000/__livereload");
socket.onmessage = function (event) {
if (event.data === "reload") {
socket.close();
location.reload();
}
};
window.onbeforeunload = function() {
socket.close();
}
</script>
<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>

2741
book/Zsh-Line-Editor.html Normal file

File diff suppressed because it is too large Load Diff

4021
book/Zsh-Modules.html Normal file

File diff suppressed because it is too large Load Diff

79
book/ayu-highlight.css Normal file
View File

@ -0,0 +1,79 @@
/*
Based off of the Ayu theme
Original by Dempfi (https://github.com/dempfi/ayu)
*/
.hljs {
display: block;
overflow-x: auto;
background: #191f26;
color: #e6e1cf;
padding: 0.5em;
}
.hljs-comment,
.hljs-quote {
color: #5c6773;
font-style: italic;
}
.hljs-variable,
.hljs-template-variable,
.hljs-attribute,
.hljs-attr,
.hljs-regexp,
.hljs-link,
.hljs-selector-id,
.hljs-selector-class {
color: #ff7733;
}
.hljs-number,
.hljs-meta,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params {
color: #ffee99;
}
.hljs-string,
.hljs-bullet {
color: #b8cc52;
}
.hljs-title,
.hljs-built_in,
.hljs-section {
color: #ffb454;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-symbol {
color: #ff7733;
}
.hljs-name {
color: #36a3d9;
}
.hljs-tag {
color: #00568d;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}
.hljs-addition {
color: #91b362;
}
.hljs-deletion {
color: #d96c75;
}

660
book/book.js Normal file
View File

@ -0,0 +1,660 @@
"use strict";
// Fix back button cache problem
window.onunload = function () { };
// Global variable, shared between modules
function playground_text(playground) {
let code_block = playground.querySelector("code");
if (window.ace && code_block.classList.contains("editable")) {
let editor = window.ace.edit(code_block);
return editor.getValue();
} else {
return code_block.textContent;
}
}
(function codeSnippets() {
function fetch_with_timeout(url, options, timeout = 6000) {
return Promise.race([
fetch(url, options),
new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), timeout))
]);
}
var playgrounds = Array.from(document.querySelectorAll(".playground"));
if (playgrounds.length > 0) {
fetch_with_timeout("https://play.rust-lang.org/meta/crates", {
headers: {
'Content-Type': "application/json",
},
method: 'POST',
mode: 'cors',
})
.then(response => response.json())
.then(response => {
// get list of crates available in the rust playground
let playground_crates = response.crates.map(item => item["id"]);
playgrounds.forEach(block => handle_crate_list_update(block, playground_crates));
});
}
function handle_crate_list_update(playground_block, playground_crates) {
// update the play buttons after receiving the response
update_play_button(playground_block, playground_crates);
// and install on change listener to dynamically update ACE editors
if (window.ace) {
let code_block = playground_block.querySelector("code");
if (code_block.classList.contains("editable")) {
let editor = window.ace.edit(code_block);
editor.addEventListener("change", function (e) {
update_play_button(playground_block, playground_crates);
});
// add Ctrl-Enter command to execute rust code
editor.commands.addCommand({
name: "run",
bindKey: {
win: "Ctrl-Enter",
mac: "Ctrl-Enter"
},
exec: _editor => run_rust_code(playground_block)
});
}
}
}
// updates the visibility of play button based on `no_run` class and
// used crates vs ones available on http://play.rust-lang.org
function update_play_button(pre_block, playground_crates) {
var play_button = pre_block.querySelector(".play-button");
// skip if code is `no_run`
if (pre_block.querySelector('code').classList.contains("no_run")) {
play_button.classList.add("hidden");
return;
}
// get list of `extern crate`'s from snippet
var txt = playground_text(pre_block);
var re = /extern\s+crate\s+([a-zA-Z_0-9]+)\s*;/g;
var snippet_crates = [];
var item;
while (item = re.exec(txt)) {
snippet_crates.push(item[1]);
}
// check if all used crates are available on play.rust-lang.org
var all_available = snippet_crates.every(function (elem) {
return playground_crates.indexOf(elem) > -1;
});
if (all_available) {
play_button.classList.remove("hidden");
} else {
play_button.classList.add("hidden");
}
}
function run_rust_code(code_block) {
var result_block = code_block.querySelector(".result");
if (!result_block) {
result_block = document.createElement('code');
result_block.className = 'result hljs language-bash';
code_block.append(result_block);
}
let text = playground_text(code_block);
let classes = code_block.querySelector('code').classList;
let has_2018 = classes.contains("edition2018");
let edition = has_2018 ? "2018" : "2015";
var params = {
version: "stable",
optimize: "0",
code: text,
edition: edition
};
if (text.indexOf("#![feature") !== -1) {
params.version = "nightly";
}
result_block.innerText = "Running...";
fetch_with_timeout("https://play.rust-lang.org/evaluate.json", {
headers: {
'Content-Type': "application/json",
},
method: 'POST',
mode: 'cors',
body: JSON.stringify(params)
})
.then(response => response.json())
.then(response => result_block.innerText = response.result)
.catch(error => result_block.innerText = "Playground Communication: " + error.message);
}
// Syntax highlighting Configuration
hljs.configure({
tabReplace: ' ', // 4 spaces
languages: [], // Languages used for auto-detection
});
let code_nodes = Array
.from(document.querySelectorAll('code'))
// Don't highlight `inline code` blocks in headers.
.filter(function (node) {return !node.parentElement.classList.contains("header"); });
if (window.ace) {
// language-rust class needs to be removed for editable
// blocks or highlightjs will capture events
Array
.from(document.querySelectorAll('code.editable'))
.forEach(function (block) { block.classList.remove('language-rust'); });
Array
.from(document.querySelectorAll('code:not(.editable)'))
.forEach(function (block) { hljs.highlightBlock(block); });
} else {
code_nodes.forEach(function (block) { hljs.highlightBlock(block); });
}
// Adding the hljs class gives code blocks the color css
// even if highlighting doesn't apply
code_nodes.forEach(function (block) { block.classList.add('hljs'); });
Array.from(document.querySelectorAll("code.language-rust")).forEach(function (block) {
var lines = Array.from(block.querySelectorAll('.boring'));
// If no lines were hidden, return
if (!lines.length) { return; }
block.classList.add("hide-boring");
var buttons = document.createElement('div');
buttons.className = 'buttons';
buttons.innerHTML = "<button class=\"fa fa-eye\" title=\"Show hidden lines\" aria-label=\"Show hidden lines\"></button>";
// add expand button
var pre_block = block.parentNode;
pre_block.insertBefore(buttons, pre_block.firstChild);
pre_block.querySelector('.buttons').addEventListener('click', function (e) {
if (e.target.classList.contains('fa-eye')) {
e.target.classList.remove('fa-eye');
e.target.classList.add('fa-eye-slash');
e.target.title = 'Hide lines';
e.target.setAttribute('aria-label', e.target.title);
block.classList.remove('hide-boring');
} else if (e.target.classList.contains('fa-eye-slash')) {
e.target.classList.remove('fa-eye-slash');
e.target.classList.add('fa-eye');
e.target.title = 'Show hidden lines';
e.target.setAttribute('aria-label', e.target.title);
block.classList.add('hide-boring');
}
});
});
if (window.playground_copyable) {
Array.from(document.querySelectorAll('pre code')).forEach(function (block) {
var pre_block = block.parentNode;
if (!pre_block.classList.contains('playground')) {
var buttons = pre_block.querySelector(".buttons");
if (!buttons) {
buttons = document.createElement('div');
buttons.className = 'buttons';
pre_block.insertBefore(buttons, pre_block.firstChild);
}
var clipButton = document.createElement('button');
clipButton.className = 'fa fa-copy clip-button';
clipButton.title = 'Copy to clipboard';
clipButton.setAttribute('aria-label', clipButton.title);
clipButton.innerHTML = '<i class=\"tooltiptext\"></i>';
buttons.insertBefore(clipButton, buttons.firstChild);
}
});
}
// Process playground code blocks
Array.from(document.querySelectorAll(".playground")).forEach(function (pre_block) {
// Add play button
var buttons = pre_block.querySelector(".buttons");
if (!buttons) {
buttons = document.createElement('div');
buttons.className = 'buttons';
pre_block.insertBefore(buttons, pre_block.firstChild);
}
var runCodeButton = document.createElement('button');
runCodeButton.className = 'fa fa-play play-button';
runCodeButton.hidden = true;
runCodeButton.title = 'Run this code';
runCodeButton.setAttribute('aria-label', runCodeButton.title);
buttons.insertBefore(runCodeButton, buttons.firstChild);
runCodeButton.addEventListener('click', function (e) {
run_rust_code(pre_block);
});
if (window.playground_copyable) {
var copyCodeClipboardButton = document.createElement('button');
copyCodeClipboardButton.className = 'fa fa-copy clip-button';
copyCodeClipboardButton.innerHTML = '<i class="tooltiptext"></i>';
copyCodeClipboardButton.title = 'Copy to clipboard';
copyCodeClipboardButton.setAttribute('aria-label', copyCodeClipboardButton.title);
buttons.insertBefore(copyCodeClipboardButton, buttons.firstChild);
}
let code_block = pre_block.querySelector("code");
if (window.ace && code_block.classList.contains("editable")) {
var undoChangesButton = document.createElement('button');
undoChangesButton.className = 'fa fa-history reset-button';
undoChangesButton.title = 'Undo changes';
undoChangesButton.setAttribute('aria-label', undoChangesButton.title);
buttons.insertBefore(undoChangesButton, buttons.firstChild);
undoChangesButton.addEventListener('click', function () {
let editor = window.ace.edit(code_block);
editor.setValue(editor.originalCode);
editor.clearSelection();
});
}
});
})();
(function themes() {
var html = document.querySelector('html');
var themeToggleButton = document.getElementById('theme-toggle');
var themePopup = document.getElementById('theme-list');
var themeColorMetaTag = document.querySelector('meta[name="theme-color"]');
var stylesheets = {
ayuHighlight: document.querySelector("[href$='ayu-highlight.css']"),
tomorrowNight: document.querySelector("[href$='tomorrow-night.css']"),
highlight: document.querySelector("[href$='highlight.css']"),
};
function showThemes() {
themePopup.style.display = 'block';
themeToggleButton.setAttribute('aria-expanded', true);
themePopup.querySelector("button#" + get_theme()).focus();
}
function hideThemes() {
themePopup.style.display = 'none';
themeToggleButton.setAttribute('aria-expanded', false);
themeToggleButton.focus();
}
function get_theme() {
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch (e) { }
if (theme === null || theme === undefined) {
return default_theme;
} else {
return theme;
}
}
function set_theme(theme, store = true) {
let ace_theme;
if (theme == 'coal' || theme == 'navy') {
stylesheets.ayuHighlight.disabled = true;
stylesheets.tomorrowNight.disabled = false;
stylesheets.highlight.disabled = true;
ace_theme = "ace/theme/tomorrow_night";
} else if (theme == 'ayu') {
stylesheets.ayuHighlight.disabled = false;
stylesheets.tomorrowNight.disabled = true;
stylesheets.highlight.disabled = true;
ace_theme = "ace/theme/tomorrow_night";
} else {
stylesheets.ayuHighlight.disabled = true;
stylesheets.tomorrowNight.disabled = true;
stylesheets.highlight.disabled = false;
ace_theme = "ace/theme/dawn";
}
setTimeout(function () {
themeColorMetaTag.content = getComputedStyle(document.body).backgroundColor;
}, 1);
if (window.ace && window.editors) {
window.editors.forEach(function (editor) {
editor.setTheme(ace_theme);
});
}
var previousTheme = get_theme();
if (store) {
try { localStorage.setItem('mdbook-theme', theme); } catch (e) { }
}
html.classList.remove(previousTheme);
html.classList.add(theme);
}
// Set theme
var theme = get_theme();
set_theme(theme, false);
themeToggleButton.addEventListener('click', function () {
if (themePopup.style.display === 'block') {
hideThemes();
} else {
showThemes();
}
});
themePopup.addEventListener('click', function (e) {
var theme = e.target.id || e.target.parentElement.id;
set_theme(theme);
});
themePopup.addEventListener('focusout', function(e) {
// e.relatedTarget is null in Safari and Firefox on macOS (see workaround below)
if (!!e.relatedTarget && !themeToggleButton.contains(e.relatedTarget) && !themePopup.contains(e.relatedTarget)) {
hideThemes();
}
});
// Should not be needed, but it works around an issue on macOS & iOS: https://github.com/rust-lang/mdBook/issues/628
document.addEventListener('click', function(e) {
if (themePopup.style.display === 'block' && !themeToggleButton.contains(e.target) && !themePopup.contains(e.target)) {
hideThemes();
}
});
document.addEventListener('keydown', function (e) {
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; }
if (!themePopup.contains(e.target)) { return; }
switch (e.key) {
case 'Escape':
e.preventDefault();
hideThemes();
break;
case 'ArrowUp':
e.preventDefault();
var li = document.activeElement.parentElement;
if (li && li.previousElementSibling) {
li.previousElementSibling.querySelector('button').focus();
}
break;
case 'ArrowDown':
e.preventDefault();
var li = document.activeElement.parentElement;
if (li && li.nextElementSibling) {
li.nextElementSibling.querySelector('button').focus();
}
break;
case 'Home':
e.preventDefault();
themePopup.querySelector('li:first-child button').focus();
break;
case 'End':
e.preventDefault();
themePopup.querySelector('li:last-child button').focus();
break;
}
});
})();
(function sidebar() {
var html = document.querySelector("html");
var sidebar = document.getElementById("sidebar");
var sidebarLinks = document.querySelectorAll('#sidebar a');
var sidebarToggleButton = document.getElementById("sidebar-toggle");
var sidebarResizeHandle = document.getElementById("sidebar-resize-handle");
var firstContact = null;
function showSidebar() {
html.classList.remove('sidebar-hidden')
html.classList.add('sidebar-visible');
Array.from(sidebarLinks).forEach(function (link) {
link.setAttribute('tabIndex', 0);
});
sidebarToggleButton.setAttribute('aria-expanded', true);
sidebar.setAttribute('aria-hidden', false);
try { localStorage.setItem('mdbook-sidebar', 'visible'); } catch (e) { }
}
var sidebarAnchorToggles = document.querySelectorAll('#sidebar a.toggle');
function toggleSection(ev) {
ev.currentTarget.parentElement.classList.toggle('expanded');
}
Array.from(sidebarAnchorToggles).forEach(function (el) {
el.addEventListener('click', toggleSection);
});
function hideSidebar() {
html.classList.remove('sidebar-visible')
html.classList.add('sidebar-hidden');
Array.from(sidebarLinks).forEach(function (link) {
link.setAttribute('tabIndex', -1);
});
sidebarToggleButton.setAttribute('aria-expanded', false);
sidebar.setAttribute('aria-hidden', true);
try { localStorage.setItem('mdbook-sidebar', 'hidden'); } catch (e) { }
}
// Toggle sidebar
sidebarToggleButton.addEventListener('click', function sidebarToggle() {
if (html.classList.contains("sidebar-hidden")) {
var current_width = parseInt(
document.documentElement.style.getPropertyValue('--sidebar-width'), 10);
if (current_width < 150) {
document.documentElement.style.setProperty('--sidebar-width', '150px');
}
showSidebar();
} else if (html.classList.contains("sidebar-visible")) {
hideSidebar();
} else {
if (getComputedStyle(sidebar)['transform'] === 'none') {
hideSidebar();
} else {
showSidebar();
}
}
});
sidebarResizeHandle.addEventListener('mousedown', initResize, false);
function initResize(e) {
window.addEventListener('mousemove', resize, false);
window.addEventListener('mouseup', stopResize, false);
html.classList.add('sidebar-resizing');
}
function resize(e) {
var pos = (e.clientX - sidebar.offsetLeft);
if (pos < 20) {
hideSidebar();
} else {
if (html.classList.contains("sidebar-hidden")) {
showSidebar();
}
pos = Math.min(pos, window.innerWidth - 100);
document.documentElement.style.setProperty('--sidebar-width', pos + 'px');
}
}
//on mouseup remove windows functions mousemove & mouseup
function stopResize(e) {
html.classList.remove('sidebar-resizing');
window.removeEventListener('mousemove', resize, false);
window.removeEventListener('mouseup', stopResize, false);
}
document.addEventListener('touchstart', function (e) {
firstContact = {
x: e.touches[0].clientX,
time: Date.now()
};
}, { passive: true });
document.addEventListener('touchmove', function (e) {
if (!firstContact)
return;
var curX = e.touches[0].clientX;
var xDiff = curX - firstContact.x,
tDiff = Date.now() - firstContact.time;
if (tDiff < 250 && Math.abs(xDiff) >= 150) {
if (xDiff >= 0 && firstContact.x < Math.min(document.body.clientWidth * 0.25, 300))
showSidebar();
else if (xDiff < 0 && curX < 300)
hideSidebar();
firstContact = null;
}
}, { passive: true });
// Scroll sidebar to current active section
var activeSection = document.getElementById("sidebar").querySelector(".active");
if (activeSection) {
// https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView
activeSection.scrollIntoView({ block: 'center' });
}
})();
(function chapterNavigation() {
document.addEventListener('keydown', function (e) {
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; }
if (window.search && window.search.hasFocus()) { return; }
switch (e.key) {
case 'ArrowRight':
e.preventDefault();
var nextButton = document.querySelector('.nav-chapters.next');
if (nextButton) {
window.location.href = nextButton.href;
}
break;
case 'ArrowLeft':
e.preventDefault();
var previousButton = document.querySelector('.nav-chapters.previous');
if (previousButton) {
window.location.href = previousButton.href;
}
break;
}
});
})();
(function clipboard() {
var clipButtons = document.querySelectorAll('.clip-button');
function hideTooltip(elem) {
elem.firstChild.innerText = "";
elem.className = 'fa fa-copy clip-button';
}
function showTooltip(elem, msg) {
elem.firstChild.innerText = msg;
elem.className = 'fa fa-copy tooltipped';
}
var clipboardSnippets = new ClipboardJS('.clip-button', {
text: function (trigger) {
hideTooltip(trigger);
let playground = trigger.closest("pre");
return playground_text(playground);
}
});
Array.from(clipButtons).forEach(function (clipButton) {
clipButton.addEventListener('mouseout', function (e) {
hideTooltip(e.currentTarget);
});
});
clipboardSnippets.on('success', function (e) {
e.clearSelection();
showTooltip(e.trigger, "Copied!");
});
clipboardSnippets.on('error', function (e) {
showTooltip(e.trigger, "Clipboard error!");
});
})();
(function scrollToTop () {
var menuTitle = document.querySelector('.menu-title');
menuTitle.addEventListener('click', function () {
document.scrollingElement.scrollTo({ top: 0, behavior: 'smooth' });
});
})();
(function controllMenu() {
var menu = document.getElementById('menu-bar');
(function controllPosition() {
var scrollTop = document.scrollingElement.scrollTop;
var prevScrollTop = scrollTop;
var minMenuY = -menu.clientHeight - 50;
// When the script loads, the page can be at any scroll (e.g. if you reforesh it).
menu.style.top = scrollTop + 'px';
// Same as parseInt(menu.style.top.slice(0, -2), but faster
var topCache = menu.style.top.slice(0, -2);
menu.classList.remove('sticky');
var stickyCache = false; // Same as menu.classList.contains('sticky'), but faster
document.addEventListener('scroll', function () {
scrollTop = Math.max(document.scrollingElement.scrollTop, 0);
// `null` means that it doesn't need to be updated
var nextSticky = null;
var nextTop = null;
var scrollDown = scrollTop > prevScrollTop;
var menuPosAbsoluteY = topCache - scrollTop;
if (scrollDown) {
nextSticky = false;
if (menuPosAbsoluteY > 0) {
nextTop = prevScrollTop;
}
} else {
if (menuPosAbsoluteY > 0) {
nextSticky = true;
} else if (menuPosAbsoluteY < minMenuY) {
nextTop = prevScrollTop + minMenuY;
}
}
if (nextSticky === true && stickyCache === false) {
menu.classList.add('sticky');
stickyCache = true;
} else if (nextSticky === false && stickyCache === true) {
menu.classList.remove('sticky');
stickyCache = false;
}
if (nextTop !== null) {
menu.style.top = nextTop + 'px';
topCache = nextTop;
}
prevScrollTop = scrollTop;
}, { passive: true });
})();
(function controllBorder() {
menu.classList.remove('bordered');
document.addEventListener('scroll', function () {
if (menu.offsetTop === 0) {
menu.classList.remove('bordered');
} else {
menu.classList.add('bordered');
}
}, { passive: true });
})();
})();

7
book/clipboard.min.js vendored Normal file

File diff suppressed because one or more lines are too long

495
book/css/chrome.css Normal file
View File

@ -0,0 +1,495 @@
/* CSS for UI elements (a.k.a. chrome) */
@import 'variables.css';
::-webkit-scrollbar {
background: var(--bg);
}
::-webkit-scrollbar-thumb {
background: var(--scrollbar);
}
html {
scrollbar-color: var(--scrollbar) var(--bg);
}
#searchresults a,
.content a:link,
a:visited,
a > .hljs {
color: var(--links);
}
/* Menu Bar */
#menu-bar,
#menu-bar-hover-placeholder {
z-index: 101;
margin: auto calc(0px - var(--page-padding));
}
#menu-bar {
position: relative;
display: flex;
flex-wrap: wrap;
background-color: var(--bg);
border-bottom-color: var(--bg);
border-bottom-width: 1px;
border-bottom-style: solid;
}
#menu-bar.sticky,
.js #menu-bar-hover-placeholder:hover + #menu-bar,
.js #menu-bar:hover,
.js.sidebar-visible #menu-bar {
position: -webkit-sticky;
position: sticky;
top: 0 !important;
}
#menu-bar-hover-placeholder {
position: sticky;
position: -webkit-sticky;
top: 0;
height: var(--menu-bar-height);
}
#menu-bar.bordered {
border-bottom-color: var(--table-border-color);
}
#menu-bar i, #menu-bar .icon-button {
position: relative;
padding: 0 8px;
z-index: 10;
line-height: var(--menu-bar-height);
cursor: pointer;
transition: color 0.5s;
}
@media only screen and (max-width: 420px) {
#menu-bar i, #menu-bar .icon-button {
padding: 0 5px;
}
}
.icon-button {
border: none;
background: none;
padding: 0;
color: inherit;
}
.icon-button i {
margin: 0;
}
.right-buttons {
margin: 0 15px;
}
.right-buttons a {
text-decoration: none;
}
.left-buttons {
display: flex;
margin: 0 5px;
}
.no-js .left-buttons {
display: none;
}
.menu-title {
display: inline-block;
font-weight: 200;
font-size: 2.4rem;
line-height: var(--menu-bar-height);
text-align: center;
margin: 0;
flex: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.js .menu-title {
cursor: pointer;
}
.menu-bar,
.menu-bar:visited,
.nav-chapters,
.nav-chapters:visited,
.mobile-nav-chapters,
.mobile-nav-chapters:visited,
.menu-bar .icon-button,
.menu-bar a i {
color: var(--icons);
}
.menu-bar i:hover,
.menu-bar .icon-button:hover,
.nav-chapters:hover,
.mobile-nav-chapters i:hover {
color: var(--icons-hover);
}
/* Nav Icons */
.nav-chapters {
font-size: 2.5em;
text-align: center;
text-decoration: none;
position: fixed;
top: 0;
bottom: 0;
margin: 0;
max-width: 150px;
min-width: 90px;
display: flex;
justify-content: center;
align-content: center;
flex-direction: column;
transition: color 0.5s, background-color 0.5s;
}
.nav-chapters:hover {
text-decoration: none;
background-color: var(--theme-hover);
transition: background-color 0.15s, color 0.15s;
}
.nav-wrapper {
margin-top: 50px;
display: none;
}
.mobile-nav-chapters {
font-size: 2.5em;
text-align: center;
text-decoration: none;
width: 90px;
border-radius: 5px;
background-color: var(--sidebar-bg);
}
.previous {
float: left;
}
.next {
float: right;
right: var(--page-padding);
}
@media only screen and (max-width: 1080px) {
.nav-wide-wrapper { display: none; }
.nav-wrapper { display: block; }
}
@media only screen and (max-width: 1380px) {
.sidebar-visible .nav-wide-wrapper { display: none; }
.sidebar-visible .nav-wrapper { display: block; }
}
/* Inline code */
:not(pre) > .hljs {
display: inline;
padding: 0.1em 0.3em;
border-radius: 3px;
}
:not(pre):not(a) > .hljs {
color: var(--inline-code-color);
overflow-x: initial;
}
a:hover > .hljs {
text-decoration: underline;
}
pre {
position: relative;
}
pre > .buttons {
position: absolute;
z-index: 100;
right: 5px;
top: 5px;
color: var(--sidebar-fg);
cursor: pointer;
}
pre > .buttons :hover {
color: var(--sidebar-active);
}
pre > .buttons i {
margin-left: 8px;
}
pre > .buttons button {
color: inherit;
background: transparent;
border: none;
cursor: inherit;
}
pre > .result {
margin-top: 10px;
}
/* Search */
#searchresults a {
text-decoration: none;
}
mark {
border-radius: 2px;
padding: 0 3px 1px 3px;
margin: 0 -3px -1px -3px;
background-color: var(--search-mark-bg);
transition: background-color 300ms linear;
cursor: pointer;
}
mark.fade-out {
background-color: rgba(0,0,0,0) !important;
cursor: auto;
}
.searchbar-outer {
margin-left: auto;
margin-right: auto;
max-width: var(--content-max-width);
}
#searchbar {
width: 100%;
margin: 5px auto 0px auto;
padding: 10px 16px;
transition: box-shadow 300ms ease-in-out;
border: 1px solid var(--searchbar-border-color);
border-radius: 3px;
background-color: var(--searchbar-bg);
color: var(--searchbar-fg);
}
#searchbar:focus,
#searchbar.active {
box-shadow: 0 0 3px var(--searchbar-shadow-color);
}
.searchresults-header {
font-weight: bold;
font-size: 1em;
padding: 18px 0 0 5px;
color: var(--searchresults-header-fg);
}
.searchresults-outer {
margin-left: auto;
margin-right: auto;
max-width: var(--content-max-width);
border-bottom: 1px dashed var(--searchresults-border-color);
}
ul#searchresults {
list-style: none;
padding-left: 20px;
}
ul#searchresults li {
margin: 10px 0px;
padding: 2px;
border-radius: 2px;
}
ul#searchresults li.focus {
background-color: var(--searchresults-li-bg);
}
ul#searchresults span.teaser {
display: block;
clear: both;
margin: 5px 0 0 20px;
font-size: 0.8em;
}
ul#searchresults span.teaser em {
font-weight: bold;
font-style: normal;
}
/* Sidebar */
.sidebar {
position: fixed;
left: 0;
top: 0;
bottom: 0;
width: var(--sidebar-width);
font-size: 0.875em;
box-sizing: border-box;
-webkit-overflow-scrolling: touch;
overscroll-behavior-y: contain;
background-color: var(--sidebar-bg);
color: var(--sidebar-fg);
}
.sidebar-resizing {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
}
.js:not(.sidebar-resizing) .sidebar {
transition: transform 0.3s; /* Animation: slide away */
}
.sidebar code {
line-height: 2em;
}
.sidebar .sidebar-scrollbox {
overflow-y: auto;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
padding: 10px 10px;
}
.sidebar .sidebar-resize-handle {
position: absolute;
cursor: col-resize;
width: 0;
right: 0;
top: 0;
bottom: 0;
}
.js .sidebar .sidebar-resize-handle {
cursor: col-resize;
width: 5px;
}
.sidebar-hidden .sidebar {
transform: translateX(calc(0px - var(--sidebar-width)));
}
.sidebar::-webkit-scrollbar {
background: var(--sidebar-bg);
}
.sidebar::-webkit-scrollbar-thumb {
background: var(--scrollbar);
}
.sidebar-visible .page-wrapper {
transform: translateX(var(--sidebar-width));
}
@media only screen and (min-width: 620px) {
.sidebar-visible .page-wrapper {
transform: none;
margin-left: var(--sidebar-width);
}
}
.chapter {
list-style: none outside none;
padding-left: 0;
line-height: 2.2em;
}
.chapter ol {
width: 100%;
}
.chapter li {
display: flex;
color: var(--sidebar-non-existant);
}
.chapter li a {
display: block;
padding: 0;
text-decoration: none;
color: var(--sidebar-fg);
}
.chapter li a:hover {
color: var(--sidebar-active);
}
.chapter li a.active {
color: var(--sidebar-active);
}
.chapter li > a.toggle {
cursor: pointer;
display: block;
margin-left: auto;
padding: 0 10px;
user-select: none;
opacity: 0.68;
}
.chapter li > a.toggle div {
transition: transform 0.5s;
}
/* collapse the section */
.chapter li:not(.expanded) + li > ol {
display: none;
}
.chapter li.chapter-item {
line-height: 1.5em;
margin-top: 0.6em;
}
.chapter li.expanded > a.toggle div {
transform: rotate(90deg);
}
.spacer {
width: 100%;
height: 3px;
margin: 5px 0px;
}
.chapter .spacer {
background-color: var(--sidebar-spacer);
}
@media (-moz-touch-enabled: 1), (pointer: coarse) {
.chapter li a { padding: 5px 0; }
.spacer { margin: 10px 0; }
}
.section {
list-style: none outside none;
padding-left: 20px;
line-height: 1.9em;
}
/* Theme Menu Popup */
.theme-popup {
position: absolute;
left: 10px;
top: var(--menu-bar-height);
z-index: 1000;
border-radius: 4px;
font-size: 0.7em;
color: var(--fg);
background: var(--theme-popup-bg);
border: 1px solid var(--theme-popup-border);
margin: 0;
padding: 0;
list-style: none;
display: none;
}
.theme-popup .default {
color: var(--icons);
}
.theme-popup .theme {
width: 100%;
border: 0;
margin: 0;
padding: 2px 10px;
line-height: 25px;
white-space: nowrap;
text-align: left;
cursor: pointer;
color: inherit;
background: inherit;
font-size: inherit;
}
.theme-popup .theme:hover {
background-color: var(--theme-hover);
}
.theme-popup .theme:hover:first-child,
.theme-popup .theme:hover:last-child {
border-top-left-radius: inherit;
border-top-right-radius: inherit;
}

177
book/css/general.css Normal file
View File

@ -0,0 +1,177 @@
/* Base styles and content styles */
@import 'variables.css';
:root {
/* Browser default font-size is 16px, this way 1 rem = 10px */
font-size: 62.5%;
}
html {
font-family: "Open Sans", sans-serif;
color: var(--fg);
background-color: var(--bg);
text-size-adjust: none;
}
body {
margin: 0;
font-size: 1.6rem;
overflow-x: hidden;
}
code {
font-family: "Source Code Pro", Consolas, "Ubuntu Mono", Menlo, "DejaVu Sans Mono", monospace, monospace !important;
font-size: 0.875em; /* please adjust the ace font size accordingly in editor.js */
}
/* Don't change font size in headers. */
h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
font-size: unset;
}
.left { float: left; }
.right { float: right; }
.boring { opacity: 0.6; }
.hide-boring .boring { display: none; }
.hidden { display: none !important; }
h2, h3 { margin-top: 2.5em; }
h4, h5 { margin-top: 2em; }
.header + .header h3,
.header + .header h4,
.header + .header h5 {
margin-top: 1em;
}
h1:target::before,
h2:target::before,
h3:target::before,
h4:target::before,
h5:target::before,
h6:target::before {
display: inline-block;
content: "»";
margin-left: -30px;
width: 30px;
}
/* This is broken on Safari as of version 14, but is fixed
in Safari Technology Preview 117 which I think will be Safari 14.2.
https://bugs.webkit.org/show_bug.cgi?id=218076
*/
:target {
scroll-margin-top: calc(var(--menu-bar-height) + 0.5em);
}
.page {
outline: 0;
padding: 0 var(--page-padding);
margin-top: calc(0px - var(--menu-bar-height)); /* Compensate for the #menu-bar-hover-placeholder */
}
.page-wrapper {
box-sizing: border-box;
}
.js:not(.sidebar-resizing) .page-wrapper {
transition: margin-left 0.3s ease, transform 0.3s ease; /* Animation: slide away */
}
.content {
overflow-y: auto;
padding: 0 15px;
padding-bottom: 50px;
}
.content main {
margin-left: auto;
margin-right: auto;
max-width: var(--content-max-width);
}
.content p { line-height: 1.45em; }
.content ol { line-height: 1.45em; }
.content ul { line-height: 1.45em; }
.content a { text-decoration: none; }
.content a:hover { text-decoration: underline; }
.content img { max-width: 100%; }
.content .header:link,
.content .header:visited {
color: var(--fg);
}
.content .header:link,
.content .header:visited:hover {
text-decoration: none;
}
table {
margin: 0 auto;
border-collapse: collapse;
}
table td {
padding: 3px 20px;
border: 1px var(--table-border-color) solid;
}
table thead {
background: var(--table-header-bg);
}
table thead td {
font-weight: 700;
border: none;
}
table thead th {
padding: 3px 20px;
}
table thead tr {
border: 1px var(--table-header-bg) solid;
}
/* Alternate background colors for rows */
table tbody tr:nth-child(2n) {
background: var(--table-alternate-bg);
}
blockquote {
margin: 20px 0;
padding: 0 20px;
color: var(--fg);
background-color: var(--quote-bg);
border-top: .1em solid var(--quote-border);
border-bottom: .1em solid var(--quote-border);
}
:not(.footnote-definition) + .footnote-definition,
.footnote-definition + :not(.footnote-definition) {
margin-top: 2em;
}
.footnote-definition {
font-size: 0.9em;
margin: 0.5em 0;
}
.footnote-definition p {
display: inline;
}
.tooltiptext {
position: absolute;
visibility: hidden;
color: #fff;
background-color: #333;
transform: translateX(-50%); /* Center by moving tooltip 50% of its width left */
left: -8px; /* Half of the width of the icon */
top: -35px;
font-size: 0.8em;
text-align: center;
border-radius: 6px;
padding: 5px 8px;
margin: 5px;
z-index: 1000;
}
.tooltipped .tooltiptext {
visibility: visible;
}
.chapter li.part-title {
color: var(--sidebar-fg);
margin: 5px 0px;
font-weight: bold;
}

54
book/css/print.css Normal file
View File

@ -0,0 +1,54 @@
#sidebar,
#menu-bar,
.nav-chapters,
.mobile-nav-chapters {
display: none;
}
#page-wrapper.page-wrapper {
transform: none;
margin-left: 0px;
overflow-y: initial;
}
#content {
max-width: none;
margin: 0;
padding: 0;
}
.page {
overflow-y: initial;
}
code {
background-color: #666666;
border-radius: 5px;
/* Force background to be printed in Chrome */
-webkit-print-color-adjust: exact;
}
pre > .buttons {
z-index: 2;
}
a, a:visited, a:active, a:hover {
color: #4183c4;
text-decoration: none;
}
h1, h2, h3, h4, h5, h6 {
page-break-inside: avoid;
page-break-after: avoid;
}
pre, code {
page-break-inside: avoid;
white-space: pre-wrap;
}
.fa {
display: none !important;
}

253
book/css/variables.css Normal file
View File

@ -0,0 +1,253 @@
/* Globals */
:root {
--sidebar-width: 300px;
--page-padding: 15px;
--content-max-width: 750px;
--menu-bar-height: 50px;
}
/* Themes */
.ayu {
--bg: hsl(210, 25%, 8%);
--fg: #c5c5c5;
--sidebar-bg: #14191f;
--sidebar-fg: #c8c9db;
--sidebar-non-existant: #5c6773;
--sidebar-active: #ffb454;
--sidebar-spacer: #2d334f;
--scrollbar: var(--sidebar-fg);
--icons: #737480;
--icons-hover: #b7b9cc;
--links: #0096cf;
--inline-code-color: #ffb454;
--theme-popup-bg: #14191f;
--theme-popup-border: #5c6773;
--theme-hover: #191f26;
--quote-bg: hsl(226, 15%, 17%);
--quote-border: hsl(226, 15%, 22%);
--table-border-color: hsl(210, 25%, 13%);
--table-header-bg: hsl(210, 25%, 28%);
--table-alternate-bg: hsl(210, 25%, 11%);
--searchbar-border-color: #848484;
--searchbar-bg: #424242;
--searchbar-fg: #fff;
--searchbar-shadow-color: #d4c89f;
--searchresults-header-fg: #666;
--searchresults-border-color: #888;
--searchresults-li-bg: #252932;
--search-mark-bg: #e3b171;
}
.coal {
--bg: hsl(200, 7%, 8%);
--fg: #98a3ad;
--sidebar-bg: #292c2f;
--sidebar-fg: #a1adb8;
--sidebar-non-existant: #505254;
--sidebar-active: #3473ad;
--sidebar-spacer: #393939;
--scrollbar: var(--sidebar-fg);
--icons: #43484d;
--icons-hover: #b3c0cc;
--links: #2b79a2;
--inline-code-color: #c5c8c6;;
--theme-popup-bg: #141617;
--theme-popup-border: #43484d;
--theme-hover: #1f2124;
--quote-bg: hsl(234, 21%, 18%);
--quote-border: hsl(234, 21%, 23%);
--table-border-color: hsl(200, 7%, 13%);
--table-header-bg: hsl(200, 7%, 28%);
--table-alternate-bg: hsl(200, 7%, 11%);
--searchbar-border-color: #aaa;
--searchbar-bg: #b7b7b7;
--searchbar-fg: #000;
--searchbar-shadow-color: #aaa;
--searchresults-header-fg: #666;
--searchresults-border-color: #98a3ad;
--searchresults-li-bg: #2b2b2f;
--search-mark-bg: #355c7d;
}
.light {
--bg: hsl(0, 0%, 100%);
--fg: hsl(0, 0%, 0%);
--sidebar-bg: #fafafa;
--sidebar-fg: hsl(0, 0%, 0%);
--sidebar-non-existant: #aaaaaa;
--sidebar-active: #1f1fff;
--sidebar-spacer: #f4f4f4;
--scrollbar: #8F8F8F;
--icons: #747474;
--icons-hover: #000000;
--links: #20609f;
--inline-code-color: #301900;
--theme-popup-bg: #fafafa;
--theme-popup-border: #cccccc;
--theme-hover: #e6e6e6;
--quote-bg: hsl(197, 37%, 96%);
--quote-border: hsl(197, 37%, 91%);
--table-border-color: hsl(0, 0%, 95%);
--table-header-bg: hsl(0, 0%, 80%);
--table-alternate-bg: hsl(0, 0%, 97%);
--searchbar-border-color: #aaa;
--searchbar-bg: #fafafa;
--searchbar-fg: #000;
--searchbar-shadow-color: #aaa;
--searchresults-header-fg: #666;
--searchresults-border-color: #888;
--searchresults-li-bg: #e4f2fe;
--search-mark-bg: #a2cff5;
}
.navy {
--bg: hsl(226, 23%, 11%);
--fg: #bcbdd0;
--sidebar-bg: #282d3f;
--sidebar-fg: #c8c9db;
--sidebar-non-existant: #505274;
--sidebar-active: #2b79a2;
--sidebar-spacer: #2d334f;
--scrollbar: var(--sidebar-fg);
--icons: #737480;
--icons-hover: #b7b9cc;
--links: #2b79a2;
--inline-code-color: #c5c8c6;;
--theme-popup-bg: #161923;
--theme-popup-border: #737480;
--theme-hover: #282e40;
--quote-bg: hsl(226, 15%, 17%);
--quote-border: hsl(226, 15%, 22%);
--table-border-color: hsl(226, 23%, 16%);
--table-header-bg: hsl(226, 23%, 31%);
--table-alternate-bg: hsl(226, 23%, 14%);
--searchbar-border-color: #aaa;
--searchbar-bg: #aeaec6;
--searchbar-fg: #000;
--searchbar-shadow-color: #aaa;
--searchresults-header-fg: #5f5f71;
--searchresults-border-color: #5c5c68;
--searchresults-li-bg: #242430;
--search-mark-bg: #a2cff5;
}
.rust {
--bg: hsl(60, 9%, 87%);
--fg: #262625;
--sidebar-bg: #3b2e2a;
--sidebar-fg: #c8c9db;
--sidebar-non-existant: #505254;
--sidebar-active: #e69f67;
--sidebar-spacer: #45373a;
--scrollbar: var(--sidebar-fg);
--icons: #737480;
--icons-hover: #262625;
--links: #2b79a2;
--inline-code-color: #6e6b5e;
--theme-popup-bg: #e1e1db;
--theme-popup-border: #b38f6b;
--theme-hover: #99908a;
--quote-bg: hsl(60, 5%, 75%);
--quote-border: hsl(60, 5%, 70%);
--table-border-color: hsl(60, 9%, 82%);
--table-header-bg: #b3a497;
--table-alternate-bg: hsl(60, 9%, 84%);
--searchbar-border-color: #aaa;
--searchbar-bg: #fafafa;
--searchbar-fg: #000;
--searchbar-shadow-color: #aaa;
--searchresults-header-fg: #666;
--searchresults-border-color: #888;
--searchresults-li-bg: #dec2a2;
--search-mark-bg: #e69f67;
}
@media (prefers-color-scheme: dark) {
.light.no-js {
--bg: hsl(200, 7%, 8%);
--fg: #98a3ad;
--sidebar-bg: #292c2f;
--sidebar-fg: #a1adb8;
--sidebar-non-existant: #505254;
--sidebar-active: #3473ad;
--sidebar-spacer: #393939;
--scrollbar: var(--sidebar-fg);
--icons: #43484d;
--icons-hover: #b3c0cc;
--links: #2b79a2;
--inline-code-color: #c5c8c6;;
--theme-popup-bg: #141617;
--theme-popup-border: #43484d;
--theme-hover: #1f2124;
--quote-bg: hsl(234, 21%, 18%);
--quote-border: hsl(234, 21%, 23%);
--table-border-color: hsl(200, 7%, 13%);
--table-header-bg: hsl(200, 7%, 28%);
--table-alternate-bg: hsl(200, 7%, 11%);
--searchbar-border-color: #aaa;
--searchbar-bg: #b7b7b7;
--searchbar-fg: #000;
--searchbar-shadow-color: #aaa;
--searchresults-header-fg: #666;
--searchresults-border-color: #98a3ad;
--searchresults-li-bg: #2b2b2f;
--search-mark-bg: #355c7d;
}
}

10
book/elasticlunr.min.js vendored Normal file

File diff suppressed because one or more lines are too long

BIN
book/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

22
book/favicon.svg Normal file
View File

@ -0,0 +1,22 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 199.7 184.2">
<style>
@media (prefers-color-scheme: dark) {
svg { fill: white; }
}
</style>
<path d="M189.5,36.8c0.2,2.8,0,5.1-0.6,6.8L153,162c-0.6,2.1-2,3.7-4.2,5c-2.2,1.2-4.4,1.9-6.7,1.9H31.4c-9.6,0-15.3-2.8-17.3-8.4
c-0.8-2.2-0.8-3.9,0.1-5.2c0.9-1.2,2.4-1.8,4.6-1.8H123c7.4,0,12.6-1.4,15.4-4.1s5.7-8.9,8.6-18.4l32.9-108.6
c1.8-5.9,1-11.1-2.2-15.6S169.9,0,164,0H72.7c-1,0-3.1,0.4-6.1,1.1l0.1-0.4C64.5,0.2,62.6,0,61,0.1s-3,0.5-4.3,1.4
c-1.3,0.9-2.4,1.8-3.2,2.8S52,6.5,51.2,8.1c-0.8,1.6-1.4,3-1.9,4.3s-1.1,2.7-1.8,4.2c-0.7,1.5-1.3,2.7-2,3.7c-0.5,0.6-1.2,1.5-2,2.5
s-1.6,2-2.2,2.8s-0.9,1.5-1.1,2.2c-0.2,0.7-0.1,1.8,0.2,3.2c0.3,1.4,0.4,2.4,0.4,3.1c-0.3,3-1.4,6.9-3.3,11.6
c-1.9,4.7-3.6,8.1-5.1,10.1c-0.3,0.4-1.2,1.3-2.6,2.7c-1.4,1.4-2.3,2.6-2.6,3.7c-0.3,0.4-0.3,1.5-0.1,3.4c0.3,1.8,0.4,3.1,0.3,3.8
c-0.3,2.7-1.3,6.3-3,10.8c-1.7,4.5-3.4,8.2-5,11c-0.2,0.5-0.9,1.4-2,2.8c-1.1,1.4-1.8,2.5-2,3.4c-0.2,0.6-0.1,1.8,0.1,3.4
c0.2,1.6,0.2,2.8-0.1,3.6c-0.6,3-1.8,6.7-3.6,11c-1.8,4.3-3.6,7.9-5.4,11c-0.5,0.8-1.1,1.7-2,2.8c-0.8,1.1-1.5,2-2,2.8
s-0.8,1.6-1,2.5c-0.1,0.5,0,1.3,0.4,2.3c0.3,1.1,0.4,1.9,0.4,2.6c-0.1,1.1-0.2,2.6-0.5,4.4c-0.2,1.8-0.4,2.9-0.4,3.2
c-1.8,4.8-1.7,9.9,0.2,15.2c2.2,6.2,6.2,11.5,11.9,15.8c5.7,4.3,11.7,6.4,17.8,6.4h110.7c5.2,0,10.1-1.7,14.7-5.2s7.7-7.8,9.2-12.9
l33-108.6c1.8-5.8,1-10.9-2.2-15.5C194.9,39.7,192.6,38,189.5,36.8z M59.6,122.8L73.8,80c0,0,7,0,10.8,0s28.8-1.7,25.4,17.5
c-3.4,19.2-18.8,25.2-36.8,25.4S59.6,122.8,59.6,122.8z M78.6,116.8c4.7-0.1,18.9-2.9,22.1-17.1S89.2,86.3,89.2,86.3l-8.9,0
l-10.2,30.5C70.2,116.9,74,116.9,78.6,116.8z M75.3,68.7L89,26.2h9.8l0.8,34l23.6-34h9.9l-13.6,42.5h-7.1l12.5-35.4l-24.5,35.4h-6.8
l-0.8-35L82,68.7H75.3z"/>
</svg>
<!-- Original image Copyright Dave Gandy — CC BY 4.0 License -->

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,93 @@
Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries.
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

100
book/fonts/fonts.css Normal file
View File

@ -0,0 +1,100 @@
/* Open Sans is licensed under the Apache License, Version 2.0. See http://www.apache.org/licenses/LICENSE-2.0 */
/* Source Code Pro is under the Open Font License. See https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL */
/* open-sans-300 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 300;
src: local('Open Sans Light'), local('OpenSans-Light'),
url('open-sans-v17-all-charsets-300.woff2') format('woff2');
}
/* open-sans-300italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
@font-face {
font-family: 'Open Sans';
font-style: italic;
font-weight: 300;
src: local('Open Sans Light Italic'), local('OpenSans-LightItalic'),
url('open-sans-v17-all-charsets-300italic.woff2') format('woff2');
}
/* open-sans-regular - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 400;
src: local('Open Sans Regular'), local('OpenSans-Regular'),
url('open-sans-v17-all-charsets-regular.woff2') format('woff2');
}
/* open-sans-italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
@font-face {
font-family: 'Open Sans';
font-style: italic;
font-weight: 400;
src: local('Open Sans Italic'), local('OpenSans-Italic'),
url('open-sans-v17-all-charsets-italic.woff2') format('woff2');
}
/* open-sans-600 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 600;
src: local('Open Sans SemiBold'), local('OpenSans-SemiBold'),
url('open-sans-v17-all-charsets-600.woff2') format('woff2');
}
/* open-sans-600italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
@font-face {
font-family: 'Open Sans';
font-style: italic;
font-weight: 600;
src: local('Open Sans SemiBold Italic'), local('OpenSans-SemiBoldItalic'),
url('open-sans-v17-all-charsets-600italic.woff2') format('woff2');
}
/* open-sans-700 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 700;
src: local('Open Sans Bold'), local('OpenSans-Bold'),
url('open-sans-v17-all-charsets-700.woff2') format('woff2');
}
/* open-sans-700italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
@font-face {
font-family: 'Open Sans';
font-style: italic;
font-weight: 700;
src: local('Open Sans Bold Italic'), local('OpenSans-BoldItalic'),
url('open-sans-v17-all-charsets-700italic.woff2') format('woff2');
}
/* open-sans-800 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 800;
src: local('Open Sans ExtraBold'), local('OpenSans-ExtraBold'),
url('open-sans-v17-all-charsets-800.woff2') format('woff2');
}
/* open-sans-800italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
@font-face {
font-family: 'Open Sans';
font-style: italic;
font-weight: 800;
src: local('Open Sans ExtraBold Italic'), local('OpenSans-ExtraBoldItalic'),
url('open-sans-v17-all-charsets-800italic.woff2') format('woff2');
}
/* source-code-pro-500 - latin_vietnamese_latin-ext_greek_cyrillic-ext_cyrillic */
@font-face {
font-family: 'Source Code Pro';
font-style: normal;
font-weight: 500;
src: url('source-code-pro-v11-all-charsets-500.woff2') format('woff2');
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

83
book/highlight.css Normal file
View File

@ -0,0 +1,83 @@
/*
* An increased contrast highlighting scheme loosely based on the
* "Base16 Atelier Dune Light" theme by Bram de Haan
* (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/dune)
* Original Base16 color scheme by Chris Kempson
* (https://github.com/chriskempson/base16)
*/
/* Comment */
.hljs-comment,
.hljs-quote {
color: #575757;
}
/* Red */
.hljs-variable,
.hljs-template-variable,
.hljs-attribute,
.hljs-tag,
.hljs-name,
.hljs-regexp,
.hljs-link,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class {
color: #d70025;
}
/* Orange */
.hljs-number,
.hljs-meta,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params {
color: #b21e00;
}
/* Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet {
color: #008200;
}
/* Blue */
.hljs-title,
.hljs-section {
color: #0030f2;
}
/* Purple */
.hljs-keyword,
.hljs-selector-tag {
color: #9d00ec;
}
.hljs {
display: block;
overflow-x: auto;
background: #f6f7f6;
color: #000;
padding: 0.5em;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}
.hljs-addition {
color: #22863a;
background-color: #f0fff4;
}
.hljs-deletion {
color: #b31d28;
background-color: #ffeef0;
}

6
book/highlight.js Normal file

File diff suppressed because one or more lines are too long

292
book/index.html Normal file
View File

@ -0,0 +1,292 @@
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>The Z Shell Manual - Zsh Manual</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 -->
</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 "><a href="The-Z-Shell-Manual.html"><strong aria-hidden="true">1.</strong> The Z Shell Manual</a></li><li class="chapter-item expanded "><a href="Introduction.html"><strong aria-hidden="true">2.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="Roadmap.html"><strong aria-hidden="true">3.</strong> Roadmap</a></li><li class="chapter-item expanded "><a href="Invocation.html"><strong aria-hidden="true">4.</strong> Invocation</a></li><li class="chapter-item expanded "><a href="Files.html"><strong aria-hidden="true">5.</strong> Files</a></li><li class="chapter-item expanded "><a href="Shell-Grammar.html"><strong aria-hidden="true">6.</strong> Shell Grammar</a></li><li class="chapter-item expanded "><a href="Redirection.html"><strong aria-hidden="true">7.</strong> Redirection</a></li><li class="chapter-item expanded "><a href="Command-Execution.html"><strong aria-hidden="true">8.</strong> Command Execution</a></li><li class="chapter-item expanded "><a href="Functions.html"><strong aria-hidden="true">9.</strong> Functions</a></li><li class="chapter-item expanded "><a href="Jobs-_0026-Signals.html"><strong aria-hidden="true">10.</strong> Jobs &amp; Signals</a></li><li class="chapter-item expanded "><a href="Arithmetic-Evaluation.html"><strong aria-hidden="true">11.</strong> Arithmetic Evaluation</a></li><li class="chapter-item expanded "><a href="Conditional-Expressions.html"><strong aria-hidden="true">12.</strong> Conditional Expressions</a></li><li class="chapter-item expanded "><a href="Prompt-Expansion.html"><strong aria-hidden="true">13.</strong> Prompt Expansion</a></li><li class="chapter-item expanded "><a href="Expansion.html"><strong aria-hidden="true">14.</strong> Expansion</a></li><li class="chapter-item expanded "><a href="Parameters.html"><strong aria-hidden="true">15.</strong> Parameters</a></li><li class="chapter-item expanded "><a href="Options.html"><strong aria-hidden="true">16.</strong> Options</a></li><li class="chapter-item expanded "><a href="Shell-Builtin-Commands.html"><strong aria-hidden="true">17.</strong> Shell Builtin Commands</a></li><li class="chapter-item expanded "><a href="Zsh-Line-Editor.html"><strong aria-hidden="true">18.</strong> Zsh Line Editor</a></li><li class="chapter-item expanded "><a href="Completion-Widgets.html"><strong aria-hidden="true">19.</strong> Completion Widgets</a></li><li class="chapter-item expanded "><a href="Completion-System.html"><strong aria-hidden="true">20.</strong> Completion System</a></li><li class="chapter-item expanded "><a href="Completion-Using-compctl.html"><strong aria-hidden="true">21.</strong> Completion Using compctl</a></li><li class="chapter-item expanded "><a href="Zsh-Modules.html"><strong aria-hidden="true">22.</strong> Zsh Modules</a></li><li class="chapter-item expanded "><a href="Calendar-Function-System.html"><strong aria-hidden="true">23.</strong> Calendar Function System</a></li><li class="chapter-item expanded "><a href="TCP-Function-System.html"><strong aria-hidden="true">24.</strong> TCP Function System</a></li><li class="chapter-item expanded "><a href="Zftp-Function-System.html"><strong aria-hidden="true">25.</strong> Zftp Function System</a></li><li class="chapter-item expanded "><a href="User-Contributions.html"><strong aria-hidden="true">26.</strong> User Contributions</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>
</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 Manual</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" name="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="#1-the-z-shell-manual">1 The Z Shell Manual</a>
<ul>
<li><a href="#11-producing-documentation-from-zshtexi">1.1 Producing documentation from zsh.texi</a></li>
</ul>
</li>
</ul>
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<p><span id="The-Z-Shell-Manual"></span>
<span id="The-Z-Shell-Manual-1"></span></p>
<h1 id="1-the-z-shell-manual"><a class="header" href="#1-the-z-shell-manual">1 The Z Shell Manual</a></h1>
<p>This document has been produced from the texinfo file <code>zsh.texi</code>,
included in the <code>Doc</code> sub-directory of the Zsh distribution.</p>
<hr />
<p><span id="Producing-documentation-from-zsh_002etexi"></span></p>
<h2 id="11-producing-documentation-from-zshtexi"><a class="header" href="#11-producing-documentation-from-zshtexi">1.1 Producing documentation from zsh.texi</a></h2>
<p>The texinfo source may be converted into several formats:</p>
<ul>
<li>
<p>The Info manual<br />
The Info format allows searching for topics, commands, functions,
etc. from the many Indices. The command <code>makeinfo zsh.texi</code> is
used to produce the Info documentation.</p>
</li>
<li>
<p>The printed manual<br />
The command <code>texi2dvi zsh.texi</code> will output <code>zsh.dvi</code> which can
then be processed with dvips and optionally gs (Ghostscript) to
produce a nicely formatted printed manual.</p>
</li>
<li>
<p>The HTML manual<br />
An HTML version of this manual is available at the Zsh web site via:</p>
<p><code>http://zsh.sourceforge.net/Doc/</code>.</p>
<p>(The HTML version is produced with texi2html, which may be obtained
from <code>http://www.nongnu.org/texi2html/</code>. The command is <code>texi2html output . ifinfo split=chapter node-files zsh.texi</code>. If
necessary, upgrade to version 1.78 of texi2html.)</p>
</li>
</ul>
<p>For those who do not have the necessary tools to process texinfo,
precompiled documentation (PostScript, dvi, PDF, info and HTML formats)
is available from the zsh archive site or its mirrors, in the file
<code>zsh-doc.tar.gz</code>. (See <a href="Introduction.html#Availability">Availability</a>
for a list of sites.)</p>
<hr />
<p>This document was generated on <em>February 15, 2020</em> using
<a href="http://www.nongnu.org/texi2html/"><em>texi2html 5.0</em></a>.<br />
Zsh version 5.8, released on February 14, 2020.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="next" href="Introduction.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="next" href="Introduction.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>
<!-- Livereload script (if served using the cli tool) -->
<script type="text/javascript">
var socket = new WebSocket("ws://localhost:3000/__livereload");
socket.onmessage = function (event) {
if (event.data === "reload") {
socket.close();
location.reload();
}
};
window.onbeforeunload = function() {
socket.close();
}
</script>
<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>

7
book/mark.min.js vendored Normal file

File diff suppressed because one or more lines are too long

33936
book/print.html Normal file

File diff suppressed because it is too large Load Diff

483
book/searcher.js Normal file
View File

@ -0,0 +1,483 @@
"use strict";
window.search = window.search || {};
(function search(search) {
// Search functionality
//
// You can use !hasFocus() to prevent keyhandling in your key
// event handlers while the user is typing their search.
if (!Mark || !elasticlunr) {
return;
}
//IE 11 Compatibility from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith
if (!String.prototype.startsWith) {
String.prototype.startsWith = function(search, pos) {
return this.substr(!pos || pos < 0 ? 0 : +pos, search.length) === search;
};
}
var search_wrap = document.getElementById('search-wrapper'),
searchbar = document.getElementById('searchbar'),
searchbar_outer = document.getElementById('searchbar-outer'),
searchresults = document.getElementById('searchresults'),
searchresults_outer = document.getElementById('searchresults-outer'),
searchresults_header = document.getElementById('searchresults-header'),
searchicon = document.getElementById('search-toggle'),
content = document.getElementById('content'),
searchindex = null,
doc_urls = [],
results_options = {
teaser_word_count: 30,
limit_results: 30,
},
search_options = {
bool: "AND",
expand: true,
fields: {
title: {boost: 1},
body: {boost: 1},
breadcrumbs: {boost: 0}
}
},
mark_exclude = [],
marker = new Mark(content),
current_searchterm = "",
URL_SEARCH_PARAM = 'search',
URL_MARK_PARAM = 'highlight',
teaser_count = 0,
SEARCH_HOTKEY_KEYCODE = 83,
ESCAPE_KEYCODE = 27,
DOWN_KEYCODE = 40,
UP_KEYCODE = 38,
SELECT_KEYCODE = 13;
function hasFocus() {
return searchbar === document.activeElement;
}
function removeChildren(elem) {
while (elem.firstChild) {
elem.removeChild(elem.firstChild);
}
}
// Helper to parse a url into its building blocks.
function parseURL(url) {
var a = document.createElement('a');
a.href = url;
return {
source: url,
protocol: a.protocol.replace(':',''),
host: a.hostname,
port: a.port,
params: (function(){
var ret = {};
var seg = a.search.replace(/^\?/,'').split('&');
var len = seg.length, i = 0, s;
for (;i<len;i++) {
if (!seg[i]) { continue; }
s = seg[i].split('=');
ret[s[0]] = s[1];
}
return ret;
})(),
file: (a.pathname.match(/\/([^/?#]+)$/i) || [,''])[1],
hash: a.hash.replace('#',''),
path: a.pathname.replace(/^([^/])/,'/$1')
};
}
// Helper to recreate a url string from its building blocks.
function renderURL(urlobject) {
var url = urlobject.protocol + "://" + urlobject.host;
if (urlobject.port != "") {
url += ":" + urlobject.port;
}
url += urlobject.path;
var joiner = "?";
for(var prop in urlobject.params) {
if(urlobject.params.hasOwnProperty(prop)) {
url += joiner + prop + "=" + urlobject.params[prop];
joiner = "&";
}
}
if (urlobject.hash != "") {
url += "#" + urlobject.hash;
}
return url;
}
// Helper to escape html special chars for displaying the teasers
var escapeHTML = (function() {
var MAP = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&#34;',
"'": '&#39;'
};
var repl = function(c) { return MAP[c]; };
return function(s) {
return s.replace(/[&<>'"]/g, repl);
};
})();
function formatSearchMetric(count, searchterm) {
if (count == 1) {
return count + " search result for '" + searchterm + "':";
} else if (count == 0) {
return "No search results for '" + searchterm + "'.";
} else {
return count + " search results for '" + searchterm + "':";
}
}
function formatSearchResult(result, searchterms) {
var teaser = makeTeaser(escapeHTML(result.doc.body), searchterms);
teaser_count++;
// The ?URL_MARK_PARAM= parameter belongs inbetween the page and the #heading-anchor
var url = doc_urls[result.ref].split("#");
if (url.length == 1) { // no anchor found
url.push("");
}
// encodeURIComponent escapes all chars that could allow an XSS except
// for '. Due to that we also manually replace ' with its url-encoded
// representation (%27).
var searchterms = encodeURIComponent(searchterms.join(" ")).replace(/\'/g, "%27");
return '<a href="' + path_to_root + url[0] + '?' + URL_MARK_PARAM + '=' + searchterms + '#' + url[1]
+ '" aria-details="teaser_' + teaser_count + '">' + result.doc.breadcrumbs + '</a>'
+ '<span class="teaser" id="teaser_' + teaser_count + '" aria-label="Search Result Teaser">'
+ teaser + '</span>';
}
function makeTeaser(body, searchterms) {
// The strategy is as follows:
// First, assign a value to each word in the document:
// Words that correspond to search terms (stemmer aware): 40
// Normal words: 2
// First word in a sentence: 8
// Then use a sliding window with a constant number of words and count the
// sum of the values of the words within the window. Then use the window that got the
// maximum sum. If there are multiple maximas, then get the last one.
// Enclose the terms in <em>.
var stemmed_searchterms = searchterms.map(function(w) {
return elasticlunr.stemmer(w.toLowerCase());
});
var searchterm_weight = 40;
var weighted = []; // contains elements of ["word", weight, index_in_document]
// split in sentences, then words
var sentences = body.toLowerCase().split('. ');
var index = 0;
var value = 0;
var searchterm_found = false;
for (var sentenceindex in sentences) {
var words = sentences[sentenceindex].split(' ');
value = 8;
for (var wordindex in words) {
var word = words[wordindex];
if (word.length > 0) {
for (var searchtermindex in stemmed_searchterms) {
if (elasticlunr.stemmer(word).startsWith(stemmed_searchterms[searchtermindex])) {
value = searchterm_weight;
searchterm_found = true;
}
};
weighted.push([word, value, index]);
value = 2;
}
index += word.length;
index += 1; // ' ' or '.' if last word in sentence
};
index += 1; // because we split at a two-char boundary '. '
};
if (weighted.length == 0) {
return body;
}
var window_weight = [];
var window_size = Math.min(weighted.length, results_options.teaser_word_count);
var cur_sum = 0;
for (var wordindex = 0; wordindex < window_size; wordindex++) {
cur_sum += weighted[wordindex][1];
};
window_weight.push(cur_sum);
for (var wordindex = 0; wordindex < weighted.length - window_size; wordindex++) {
cur_sum -= weighted[wordindex][1];
cur_sum += weighted[wordindex + window_size][1];
window_weight.push(cur_sum);
};
if (searchterm_found) {
var max_sum = 0;
var max_sum_window_index = 0;
// backwards
for (var i = window_weight.length - 1; i >= 0; i--) {
if (window_weight[i] > max_sum) {
max_sum = window_weight[i];
max_sum_window_index = i;
}
};
} else {
max_sum_window_index = 0;
}
// add <em/> around searchterms
var teaser_split = [];
var index = weighted[max_sum_window_index][2];
for (var i = max_sum_window_index; i < max_sum_window_index+window_size; i++) {
var word = weighted[i];
if (index < word[2]) {
// missing text from index to start of `word`
teaser_split.push(body.substring(index, word[2]));
index = word[2];
}
if (word[1] == searchterm_weight) {
teaser_split.push("<em>")
}
index = word[2] + word[0].length;
teaser_split.push(body.substring(word[2], index));
if (word[1] == searchterm_weight) {
teaser_split.push("</em>")
}
};
return teaser_split.join('');
}
function init(config) {
results_options = config.results_options;
search_options = config.search_options;
searchbar_outer = config.searchbar_outer;
doc_urls = config.doc_urls;
searchindex = elasticlunr.Index.load(config.index);
// Set up events
searchicon.addEventListener('click', function(e) { searchIconClickHandler(); }, false);
searchbar.addEventListener('keyup', function(e) { searchbarKeyUpHandler(); }, false);
document.addEventListener('keydown', function(e) { globalKeyHandler(e); }, false);
// If the user uses the browser buttons, do the same as if a reload happened
window.onpopstate = function(e) { doSearchOrMarkFromUrl(); };
// Suppress "submit" events so the page doesn't reload when the user presses Enter
document.addEventListener('submit', function(e) { e.preventDefault(); }, false);
// If reloaded, do the search or mark again, depending on the current url parameters
doSearchOrMarkFromUrl();
}
function unfocusSearchbar() {
// hacky, but just focusing a div only works once
var tmp = document.createElement('input');
tmp.setAttribute('style', 'position: absolute; opacity: 0;');
searchicon.appendChild(tmp);
tmp.focus();
tmp.remove();
}
// On reload or browser history backwards/forwards events, parse the url and do search or mark
function doSearchOrMarkFromUrl() {
// Check current URL for search request
var url = parseURL(window.location.href);
if (url.params.hasOwnProperty(URL_SEARCH_PARAM)
&& url.params[URL_SEARCH_PARAM] != "") {
showSearch(true);
searchbar.value = decodeURIComponent(
(url.params[URL_SEARCH_PARAM]+'').replace(/\+/g, '%20'));
searchbarKeyUpHandler(); // -> doSearch()
} else {
showSearch(false);
}
if (url.params.hasOwnProperty(URL_MARK_PARAM)) {
var words = decodeURIComponent(url.params[URL_MARK_PARAM]).split(' ');
marker.mark(words, {
exclude: mark_exclude
});
var markers = document.querySelectorAll("mark");
function hide() {
for (var i = 0; i < markers.length; i++) {
markers[i].classList.add("fade-out");
window.setTimeout(function(e) { marker.unmark(); }, 300);
}
}
for (var i = 0; i < markers.length; i++) {
markers[i].addEventListener('click', hide);
}
}
}
// Eventhandler for keyevents on `document`
function globalKeyHandler(e) {
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey || e.target.type === 'textarea' || e.target.type === 'text') { return; }
if (e.keyCode === ESCAPE_KEYCODE) {
e.preventDefault();
searchbar.classList.remove("active");
setSearchUrlParameters("",
(searchbar.value.trim() !== "") ? "push" : "replace");
if (hasFocus()) {
unfocusSearchbar();
}
showSearch(false);
marker.unmark();
} else if (!hasFocus() && e.keyCode === SEARCH_HOTKEY_KEYCODE) {
e.preventDefault();
showSearch(true);
window.scrollTo(0, 0);
searchbar.select();
} else if (hasFocus() && e.keyCode === DOWN_KEYCODE) {
e.preventDefault();
unfocusSearchbar();
searchresults.firstElementChild.classList.add("focus");
} else if (!hasFocus() && (e.keyCode === DOWN_KEYCODE
|| e.keyCode === UP_KEYCODE
|| e.keyCode === SELECT_KEYCODE)) {
// not `:focus` because browser does annoying scrolling
var focused = searchresults.querySelector("li.focus");
if (!focused) return;
e.preventDefault();
if (e.keyCode === DOWN_KEYCODE) {
var next = focused.nextElementSibling;
if (next) {
focused.classList.remove("focus");
next.classList.add("focus");
}
} else if (e.keyCode === UP_KEYCODE) {
focused.classList.remove("focus");
var prev = focused.previousElementSibling;
if (prev) {
prev.classList.add("focus");
} else {
searchbar.select();
}
} else { // SELECT_KEYCODE
window.location.assign(focused.querySelector('a'));
}
}
}
function showSearch(yes) {
if (yes) {
search_wrap.classList.remove('hidden');
searchicon.setAttribute('aria-expanded', 'true');
} else {
search_wrap.classList.add('hidden');
searchicon.setAttribute('aria-expanded', 'false');
var results = searchresults.children;
for (var i = 0; i < results.length; i++) {
results[i].classList.remove("focus");
}
}
}
function showResults(yes) {
if (yes) {
searchresults_outer.classList.remove('hidden');
} else {
searchresults_outer.classList.add('hidden');
}
}
// Eventhandler for search icon
function searchIconClickHandler() {
if (search_wrap.classList.contains('hidden')) {
showSearch(true);
window.scrollTo(0, 0);
searchbar.select();
} else {
showSearch(false);
}
}
// Eventhandler for keyevents while the searchbar is focused
function searchbarKeyUpHandler() {
var searchterm = searchbar.value.trim();
if (searchterm != "") {
searchbar.classList.add("active");
doSearch(searchterm);
} else {
searchbar.classList.remove("active");
showResults(false);
removeChildren(searchresults);
}
setSearchUrlParameters(searchterm, "push_if_new_search_else_replace");
// Remove marks
marker.unmark();
}
// Update current url with ?URL_SEARCH_PARAM= parameter, remove ?URL_MARK_PARAM and #heading-anchor .
// `action` can be one of "push", "replace", "push_if_new_search_else_replace"
// and replaces or pushes a new browser history item.
// "push_if_new_search_else_replace" pushes if there is no `?URL_SEARCH_PARAM=abc` yet.
function setSearchUrlParameters(searchterm, action) {
var url = parseURL(window.location.href);
var first_search = ! url.params.hasOwnProperty(URL_SEARCH_PARAM);
if (searchterm != "" || action == "push_if_new_search_else_replace") {
url.params[URL_SEARCH_PARAM] = searchterm;
delete url.params[URL_MARK_PARAM];
url.hash = "";
} else {
delete url.params[URL_MARK_PARAM];
delete url.params[URL_SEARCH_PARAM];
}
// A new search will also add a new history item, so the user can go back
// to the page prior to searching. A updated search term will only replace
// the url.
if (action == "push" || (action == "push_if_new_search_else_replace" && first_search) ) {
history.pushState({}, document.title, renderURL(url));
} else if (action == "replace" || (action == "push_if_new_search_else_replace" && !first_search) ) {
history.replaceState({}, document.title, renderURL(url));
}
}
function doSearch(searchterm) {
// Don't search the same twice
if (current_searchterm == searchterm) { return; }
else { current_searchterm = searchterm; }
if (searchindex == null) { return; }
// Do the actual search
var results = searchindex.search(searchterm, search_options);
var resultcount = Math.min(results.length, results_options.limit_results);
// Display search metrics
searchresults_header.innerText = formatSearchMetric(resultcount, searchterm);
// Clear and insert results
var searchterms = searchterm.split(' ');
removeChildren(searchresults);
for(var i = 0; i < resultcount ; i++){
var resultElem = document.createElement('li');
resultElem.innerHTML = formatSearchResult(results[i], searchterms);
searchresults.appendChild(resultElem);
}
// Display results
showResults(true);
}
fetch(path_to_root + 'searchindex.json')
.then(response => response.json())
.then(json => init(json))
.catch(error => { // Try to load searchindex.js if fetch failed
var script = document.createElement('script');
script.src = path_to_root + 'searchindex.js';
script.onload = () => init(window.search);
document.head.appendChild(script);
});
// Exported functions
search.hasFocus = hasFocus;
})(window.search);

1
book/searchindex.js Normal file

File diff suppressed because one or more lines are too long

1
book/searchindex.json Normal file

File diff suppressed because one or more lines are too long

104
book/tomorrow-night.css Normal file
View File

@ -0,0 +1,104 @@
/* Tomorrow Night Theme */
/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */
/* Original theme - https://github.com/chriskempson/tomorrow-theme */
/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */
/* Tomorrow Comment */
.hljs-comment {
color: #969896;
}
/* Tomorrow Red */
.hljs-variable,
.hljs-attribute,
.hljs-tag,
.hljs-regexp,
.ruby .hljs-constant,
.xml .hljs-tag .hljs-title,
.xml .hljs-pi,
.xml .hljs-doctype,
.html .hljs-doctype,
.css .hljs-id,
.css .hljs-class,
.css .hljs-pseudo {
color: #cc6666;
}
/* Tomorrow Orange */
.hljs-number,
.hljs-preprocessor,
.hljs-pragma,
.hljs-built_in,
.hljs-literal,
.hljs-params,
.hljs-constant {
color: #de935f;
}
/* Tomorrow Yellow */
.ruby .hljs-class .hljs-title,
.css .hljs-rule .hljs-attribute {
color: #f0c674;
}
/* Tomorrow Green */
.hljs-string,
.hljs-value,
.hljs-inheritance,
.hljs-header,
.hljs-name,
.ruby .hljs-symbol,
.xml .hljs-cdata {
color: #b5bd68;
}
/* Tomorrow Aqua */
.hljs-title,
.css .hljs-hexcolor {
color: #8abeb7;
}
/* Tomorrow Blue */
.hljs-function,
.python .hljs-decorator,
.python .hljs-title,
.ruby .hljs-function .hljs-title,
.ruby .hljs-title .hljs-keyword,
.perl .hljs-sub,
.javascript .hljs-title,
.coffeescript .hljs-title {
color: #81a2be;
}
/* Tomorrow Purple */
.hljs-keyword,
.javascript .hljs-function {
color: #b294bb;
}
.hljs {
display: block;
overflow-x: auto;
background: #1d1f21;
color: #c5c8c6;
padding: 0.5em;
-webkit-text-size-adjust: none;
}
.coffeescript .javascript,
.javascript .xml,
.tex .hljs-formula,
.xml .javascript,
.xml .vbscript,
.xml .css,
.xml .hljs-cdata {
opacity: 0.5;
}
.hljs-addition {
color: #718c00;
}
.hljs-deletion {
color: #c82829;
}

45
generate_summary.py Normal file
View File

@ -0,0 +1,45 @@
import re
import requests
from bs4 import BeautifulSoup
# Check if input contains integer substring
def hasInteger(input):
return bool(re.search(r"(?<![\d.])[0-9]+(?![\d.])", input))
# Check if input contains float substring
def hasFloat(input):
return bool(re.findall(r"\d+\.\d+", input))
# Generate SUMMARY.md from table of contents
page = requests.get("http://zsh.sourceforge.net/Doc/Release/zsh_toc.html")
soup = BeautifulSoup(page.content, "html.parser")
results = soup.find_all("a")[5:329]
contents = []
for elem in results:
if elem not in contents:
contents.append(elem.get_text())
output = []
output.append("# Summary\n")
for item in contents:
if hasInteger(item):
if "&" in item:
title = item.lstrip("0123456789. ")
fn0 = title.replace("&", "_0026")
fn1 = fn0.replace(" ", "-") + ".md"
new_line = "- [%s](./%s)" % (title, fn1)
output.append(new_line)
else:
title = item.lstrip("0123456789. ")
filename = title.replace(" ", "-") + ".md"
new_line = "- [%s](./%s)" % (title, filename)
output.append(new_line)
else:
continue
for line in output:
print(line)

55
make_mdbook.sh Executable file
View File

@ -0,0 +1,55 @@
#!/usr/bin/env bash
set -euxo pipefail
_zsh_html_url="http://zsh.sourceforge.net/Doc/zsh_html.tar.gz"
_zsh_doc_tmp_dir="${HOME}/zsh_doc_tmp"
_zsh_html_src_dir="${_zsh_doc_tmp_dir}/zsh_html"
_zsh_md_src_dir="${_zsh_doc_tmp_dir}/zsh_md"
_mdbook_src_dir="${_zsh_doc_tmp_dir}/mdbook_src"
# Ensure zsh_doc_tmp directories exist
for dir in "${_zsh_html_src_dir}" "${_zsh_md_src_dir}" "${_mdbook_src_dir}"; do
if ! [ -d "$dir" ]; then
mkdir -p "$dir"
fi
done
# Download and extract zsh_html.tar.gz to zsh_doc_tmp_dir
wget "${_zsh_html_url}" -O "${_zsh_doc_tmp_dir}/zsh_html.tar.gz"
tar xzf "${_zsh_doc_tmp_dir}/zsh_html.tar.gz" -C "${_zsh_doc_tmp_dir}"
# For some reason, extra files are added to the archive that
# have no content besides aliases to pages that do.
# They are all less than 4k, and they are just clutter for mdbook,
# so we remove them here.
find "${_zsh_html_src_dir}" -name "*.html" -type 'f' -size -4k -delete
# Remove html noise
for file in "${_zsh_html_src_dir}"/*.html; do
sed -i '/table/d' "$file"
sed -i '/span/d' "$file"
sed -i '/valign/d' "$file"
sed -i '/\[\]{#/d' "$file"
done
# Rename file extensions from html to md, preserving the original file's name
for file in "${_zsh_html_src_dir}"/*.html; do
mv -- "$file" "${_zsh_md_src_dir}/$(basename -- "$file" .html).md"
done
# Convert html to md with pandoc
for file in "${_zsh_md_src_dir}"/*.md; do
pandoc "$file" -f html -t gfm -o "$file";
done
# Move md files to mdbook_src_dir
for file in "${_zsh_md_src_dir}"/*.md; do
mv "$file" "${_mdbook_src_dir}"/
done
# Generate TOC with doctoc
doctoc "${_mdbook_src_dir}"/*.md
# Generate SUMMARY.md from zsh_toc.html
python3 "${PWD}/generate_summary.py" > "${_mdbook_src_dir}/SUMMARY.md"

19
requirements.txt Normal file
View File

@ -0,0 +1,19 @@
appdirs==1.4.4
beautifulsoup4==4.9.3
black==21.5b0
bs4==0.0.1
certifi==2020.12.5
chardet==4.0.0
click==7.1.2
flake8==3.9.2
idna==2.10
mccabe==0.6.1
mypy-extensions==0.4.3
pathspec==0.8.1
pycodestyle==2.7.0
pyflakes==2.3.1
regex==2021.4.4
requests==2.25.1
soupsieve==2.2.1
toml==0.10.2
urllib3==1.26.4

View File

@ -0,0 +1,376 @@
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [11 Arithmetic Evaluation](#11-arithmetic-evaluation)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<span id="Arithmetic-Evaluation"></span>
<span id="Arithmetic-Evaluation-1"></span>
# 11 Arithmetic Evaluation
<span id="index-arithmetic-evaluation"></span>
<span id="index-evaluation_002c-arithmetic"></span>
<span id="index-let_002c-use-of"></span>
The shell can perform integer and floating point arithmetic, either
using the builtin `let`, or via a substitution of the form
`$((``...``))`. For integers, the shell is usually compiled to use
8-byte precision where this is available, otherwise precision is 4
bytes. This can be tested, for example, by giving the command `print -
$(( 12345678901 ))`; if the number appears unchanged, the precision is
at least 8 bytes. Floating point arithmetic always uses the double
type with whatever corresponding precision is provided by the compiler
and the library.
The `let` builtin command takes arithmetic expressions as arguments;
each is evaluated separately. Since many of the arithmetic operators, as
well as spaces, require quoting, an alternative form is provided: for
any command which begins with a `((`, all the characters until a
matching `))` are treated as a quoted expression and arithmetic
expansion performed as for an argument of `let`. More precisely,
`((``...``))` is equivalent to `let "``...``"`. The return status
is 0 if the arithmetic value of the expression is non-zero, 1 if it is
zero, and 2 if an error occurred.
For example, the following statement
<div class="example">
``` example
(( val = 2 + 1 ))
```
</div>
is equivalent to
<div class="example">
``` example
let "val = 2 + 1"
```
</div>
both assigning the value 3 to the shell variable `val` and returning a
zero status.
<span id="index-arithmetic-base"></span>
<span id="index-bases_002c-in-arithmetic"></span>
Integers can be in bases other than 10. A leading `0x` or `0X`
denotes hexadecimal and a leading `0b` or `0B` binary. Integers may
also be of the form `base``#``n`, where `base` is a decimal number
between two and thirty-six representing the arithmetic base and `n` is a
number in that base (for example, `16#ff` is 255 in hexadecimal). The
`base``#` may also be omitted, in which case base 10 is used. For
backwards compatibility the form `[``base``]``n` is also accepted.
An integer expression or a base given in the form `base``#``n` may
contain underscores (`_`) after the leading digit for visual guidance;
these are ignored in computation. Examples are `1_000_000` or
`0xffff_ffff` which are equivalent to `1000000` and `0xffffffff`
respectively.
It is also possible to specify a base to be used for output in the form
`[#``base``]`, for example `[#16]`. This is used when outputting
arithmetical substitutions or when assigning to scalar parameters, but
an explicitly defined integer or floating point parameter will not be
affected. If an integer variable is implicitly defined by an arithmetic
expression, any base specified in this way will be set as the variables
output arithmetic base as if the option `-i` `base` to the `typeset`
builtin had been used. The expression has no precedence and if it occurs
more than once in a mathematical expression, the last encountered is
used. For clarity it is recommended that it appear at the beginning of
an expression. As an example:
<div class="example">
``` example
typeset -i 16 y
print $(( [#8] x = 32, y = 32 ))
print $x $y
```
</div>
outputs first `8#40`, the rightmost value in the given output base,
and then `8#40 16#20`, because `y` has been explicitly declared to
have output base 16, while `x` (assuming it does not already exist) is
implicitly typed by the arithmetic evaluation, where it acquires the
output base 8.
The `base` may be replaced or followed by an underscore, which may
itself be followed by a positive integer (if it is missing the value 3
is used). This indicates that underscores should be inserted into the
output string, grouping the number for visual clarity. The following
integer specifies the number of digits to group together. For example:
<div class="example">
``` example
setopt cbases
print $(( [#16_4] 65536 ** 2 ))
```
</div>
outputs `0x1_0000_0000`.
The feature can be used with floating point numbers, in which case the
base must be omitted; grouping is away from the decimal point. For
example,
<div class="example">
``` example
zmodload zsh/mathfunc
print $(( [#_] sqrt(1e7) ))
```
</div>
outputs `3_162.277_660_168_379_5` (the number of decimal places shown
may vary).
<span id="index-C_005fBASES_002c-use-of"></span>
<span id="index-OCTAL_005fZEROES_002c-use-of"></span>
If the `C_BASES` option is set, hexadecimal numbers are output in the
standard C format, for example `0xFF` instead of the usual `16#FF`.
If the option `OCTAL_ZEROES` is also set (it is not by default), octal
numbers will be treated similarly and hence appear as `077` instead of
`8#77`. This option has no effect on the output of bases other than
hexadecimal and octal, and these formats are always understood on input.
When an output base is specified using the `[#``base``]` syntax, an
appropriate base prefix will be output if necessary, so that the value
output is valid syntax for input. If the `#` is doubled, for example
`[##16]`, then no base prefix is output.
Floating point constants are recognized by the presence of a decimal
point or an exponent. The decimal point may be the first character of
the constant, but the exponent character `e` or `E` may not, as it will
be taken for a parameter name. All numeric parts (before and after the
decimal point and in the exponent) may contain underscores after the
leading digit for visual guidance; these are ignored in computation.
<span id="index-arithmetic-operators"></span>
<span id="index-operators_002c-arithmetic"></span>
An arithmetic expression uses nearly the same syntax and associativity
of expressions as in C.
In the native mode of operation, the following operators are supported
(listed in decreasing order of precedence):
- `+ - ! ~ ++ `
unary plus/minus, logical NOT, complement, {pre,post}{in,de}crement
- `<< >>`
bitwise shift left, right
- `&`
bitwise AND
- `^`
bitwise XOR
- `|`
bitwise OR
- `**`
exponentiation
- `* / %`
multiplication, division, modulus (remainder)
- `+ -`
addition, subtraction
- `< > <= >=`
comparison
- `== !=`
equality and inequality
- `&&`
logical AND
- `|| ^^`
logical OR, XOR
- `? :`
ternary operator
- `= += -= *= /= %= &= ^= |= <<= >>= &&= ||= ^^= **=`
assignment
- `,`
comma operator
The operators `&&`, `||`, `&&=`, and `||=` are short-circuiting,
and only one of the latter two expressions in a ternary operator is
evaluated. Note the precedence of the bitwise AND, OR, and XOR
operators.
With the option `C_PRECEDENCES` the precedences (but no other
properties) of the operators are altered to be the same as those in most
other languages that support the relevant operators:
- `+ - ! ~ ++ `
unary plus/minus, logical NOT, complement, {pre,post}{in,de}crement
- `**`
exponentiation
- `* / %`
multiplication, division, modulus (remainder)
- `+ -`
addition, subtraction
- `<< >>`
bitwise shift left, right
- `< > <= >=`
comparison
- `== !=`
equality and inequality
- `&`
bitwise AND
- `^`
bitwise XOR
- `|`
bitwise OR
- `&&`
logical AND
- `^^`
logical XOR
- `||`
logical OR
- `? :`
ternary operator
- `= += -= *= /= %= &= ^= |= <<= >>= &&= ||= ^^= **=`
assignment
- `,`
comma operator
Note the precedence of exponentiation in both cases is below that of
unary operators, hence `-3**2` evaluates as `9`, not `-9`. Use
parentheses where necessary: `-(3**2)`. This is for compatibility with
other shells.
<span id="index-mathematical-functions_002c-use-of"></span>
<span id="index-functions_002c-math_002c-use-of"></span>
Mathematical functions can be called with the syntax
`func``(``args``)`, where the function decides if the `args` is
used as a string or a comma-separated list of arithmetic expressions.
The shell currently defines no mathematical functions by default, but
the module `zsh/mathfunc` may be loaded with the `zmodload` builtin to
provide standard floating point mathematical functions.
An expression of the form `##``x` where `x` is any character sequence
such as `a`, `^A`, or `\M-\C-x` gives the value of this character
and an expression of the form `#``name` gives the value of the first
character of the contents of the parameter `name`. Character values are
according to the character set used in the current locale; for multibyte
character handling the option `MULTIBYTE` must be set. Note that this
form is different from `$#``name`, a standard parameter substitution
which gives the length of the parameter `name`. `#\` is accepted
instead of `##`, but its use is deprecated.
Named parameters and subscripted arrays can be referenced by name within
an arithmetic expression without using the parameter expansion syntax.
For example,
<div class="example">
``` example
((val2 = val1 * 2))
```
</div>
assigns twice the value of `$val1` to the parameter named `val2`.
An internal integer representation of a named parameter can be specified
with the `integer` builtin.
<span id="index-parameters_002c-integer"></span>
<span id="index-integer-parameters"></span>
<span id="index-integer_002c-use-of"></span> Arithmetic evaluation is
performed on the value of each assignment to a named parameter declared
integer in this manner. Assigning a floating point number to an integer
results in rounding towards zero.
<span id="index-parameters_002c-floating-point"></span>
<span id="index-floating-point-parameters"></span>
<span id="index-float_002c-use-of"></span>
Likewise, floating point numbers can be declared with the `float`
builtin; there are two types, differing only in their output format, as
described for the `typeset` builtin. The output format can be bypassed
by using arithmetic substitution instead of the parameter substitution,
i.e. `${``float``}` uses the defined format, but `$((``float``))`
uses a generic floating point format.
Promotion of integer to floating point values is performed where
necessary. In addition, if any operator which requires an integer
(`&`, `|`, `^`, `<<`, `>>` and their equivalents with
assignment) is given a floating point argument, it will be silently
rounded towards zero except for `~` which rounds down.
Users should beware that, in common with many other programming
languages but not software designed for calculation, the evaluation of
an expression in zsh is taken a term at a time and promotion of integers
to floating point does not occur in terms only containing integers. A
typical result of this is that a division such as `6/8` is truncated, in
this being rounded towards 0. The `FORCE_FLOAT` shell option can be used
in scripts or functions where floating point evaluation is required
throughout.
Scalar variables can hold integer or floating point values at different
times; there is no memory of the numeric type in this case.
If a variable is first assigned in a numeric context without previously
being declared, it will be implicitly typed as `integer` or `float` and
retain that type either until the type is explicitly changed or until
the end of the scope. This can have unforeseen consequences. For
example, in the loop
<div class="example">
``` example
for (( f = 0; f < 1; f += 0.1 )); do
# use $f
done
```
</div>
if `f` has not already been declared, the first assignment will cause it
to be created as an integer, and consequently the operation `f += 0.1`
will always cause the result to be truncated to zero, so that the loop
will fail. A simple fix would be to turn the initialization into `f
= 0.0`. It is therefore best to declare numeric variables with explicit
types.
-----
This document was generated on *February 15, 2020* using
[*texi2html 5.0*](http://www.nongnu.org/texi2html/).
Zsh version 5.8, released on February 14, 2020.

File diff suppressed because it is too large Load Diff

50
src/Command-Execution.md Normal file
View File

@ -0,0 +1,50 @@
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [8 Command Execution](#8-command-execution)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<span id="Command-Execution"></span>
<span id="Command-Execution-1"></span>
# 8 Command Execution
<span id="index-command-execution"></span>
<span id="index-execution_002c-of-commands"></span>
<span id="index-command-not-found_002c-handling-of"></span>
<span id="index-command_005fnot_005ffound_005fhandler"></span>
If a command name contains no slashes, the shell attempts to locate it.
If there exists a shell function by that name, the function is invoked
as described in [Functions](Functions.html#Functions). If there exists a
shell builtin by that name, the builtin is invoked.
<span id="index-path_002c-use-of"></span>
Otherwise, the shell searches each element of `$path` for a search is
unsuccessful, the shell prints an error message and returns a nonzero
exit status.
and the file is not a directory, it is assumed to be a shell script.
`/bin/sh` is spawned to execute it. If the program is a file beginning
with `#!`, the remainder of the first line specifies an interpreter
for the program. The shell will execute the specified interpreter on
operating systems that do
If no external command is found but a function
`command_not_found_handler` exists the shell executes this function with
all command line arguments. The return status of the function becomes
the status of the command. If the function wishes to mimic the behaviour
of the shell when the command is not found, it should print the message
`command not found:` `cmd` to standard error and return status 127.
Note that the handler is executed in a subshell forked to execute an
external command, hence changes to directories, shell parameters, etc.
have no effect on the main shell.
-----
This document was generated on *February 15, 2020* using
[*texi2html 5.0*](http://www.nongnu.org/texi2html/).
Zsh version 5.8, released on February 14, 2020.

6280
src/Completion-System.md Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,794 @@
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [21 Completion Using compctl](#21-completion-using-compctl)
- [21.1 Types of completion](#211-types-of-completion)
- [21.2 Description](#212-description)
- [21.3 Command Flags](#213-command-flags)
- [21.4 Option Flags](#214-option-flags)
- [21.4.1 Simple Flags](#2141-simple-flags)
- [21.4.2 Flags with Arguments](#2142-flags-with-arguments)
- [21.4.3 Control Flags](#2143-control-flags)
- [21.5 Alternative Completion](#215-alternative-completion)
- [21.6 Extended Completion](#216-extended-completion)
- [21.7 Example](#217-example)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<span id="Completion-Using-compctl"></span>
<span id="Completion-Using-compctl-1"></span>
# 21 Completion Using compctl
<span id="index-completion_002c-programmable-2"></span>
<span id="index-completion_002c-controlling-2"></span>
-----
<span id="Types-of-completion"></span>
## 21.1 Types of completion
This version of zsh has two ways of performing completion of words on
the command line. New users of the shell may prefer to use the newer and
more powerful system based on shell functions; this is described in
[Completion System](Completion-System.html#Completion-System), and the
basic shell mechanisms which support it are described in [Completion
Widgets](Completion-Widgets.html#Completion-Widgets). This chapter
describes the older `compctl` command.
-----
<span id="Description-7"></span>
## 21.2 Description
<span id="index-compctl"></span>
`compctl` \[ `-CDT` \] `options` \[ `command` ... \]
` compctl `\[ `-CDT` \] `options` \[ `-x` `pattern` `options` `-` ...
`-``-` \]
`        `\[ `+` `options` \[ `-x` ... `-``-` \] ... \[`+`\] \] \[
`command` ... \]
`compctl` `-M` `match-specs` ...
`compctl` `-L` \[ `-CDTM` \] \[ `command` ... \]
`compctl` `+` `command` ...
Control the editors completion behavior according to the supplied set
of `options`. Various editing commands, notably
`expand-or-complete-word`, usually bound to tab, will attempt to
complete a word typed by the user, while others, notably
`delete-char-or-list`, usually bound to ^D in EMACS editing mode, list
the possibilities; `compctl` controls what those possibilities are. They
may for example be filenames (the most common case, and hence the
default), shell variables, or words from a user-specified list.
-----
<span id="Command-Flags"></span> <span id="Command-Flags-1"></span>
## 21.3 Command Flags
Completion of the arguments of a command may be different for each
command or may use the default. The behavior when completing the command
word itself may also be separately specified. These correspond to the
following flags and arguments, all of which (except for `-L`) may be
combined with any combination of the `options` described subsequently in
[Option Flags](#Option-Flags):
- `command` ...
controls completion for the named commands, which must be listed
last on the command line. If completion is attempted for a command
with a pathname containing slashes and no completion definition is
found, the search is retried with the last pathname component. If
the command starts with a `=`, completion is tried with the pathname
of the command.
Any of the `command` strings may be patterns of the form normally
used for filename generation. These should be quoted to protect them
from immediate expansion; for example the command string `foo*`
arranges for completion of the words of any command beginning with
`foo`. When completion is attempted, all pattern completions are
tried in the reverse order of their definition until one matches. By
default, completion then proceeds as normal, i.e. the shell will try
to generate more matches for the specific command on the command
line; this can be overridden by including `-tn` in the flags for the
pattern completion.
Note that aliases are expanded before the command name is determined
unless the `COMPLETE_ALIASES` option is set. Commands may not be
combined with the `-C`, `-D` or `-T` flags.
- `-C`
controls completion when the command word itself is being completed.
If no `compctl -C` command has been issued, the names of any as
aliases or functions) are completed.
- `-D`
controls default completion behavior for the arguments of commands
not assigned any special behavior. If no `compctl -D` command has
been issued, filenames are completed.
- `-T`
supplies completion flags to be used before any other processing is
done, even before processing for `compctl`s defined for specific
commands. This is especially useful when combined with extended
completion (the `-x` flag, see [Extended
Completion](#Extended-Completion) below). Using this flag you can
define default behavior which will apply to all commands without
exception, or you can alter the standard behavior for all commands.
For example, if your access to the user database is too slow and/or
it contains too many users (so that completion after `~` is too
slow to be usable), you can use
<div class="example">
``` example
compctl -T -x 's[~] C[0,[^/]#]' -k friends -S/ -tn
```
</div>
to complete the strings in the array `friends` after a `~`. The
`C[``...``]` argument is necessary so that this form of
`~`-completion is not tried after the directory name is finished.
- `-L`
*no argument*
If no argument is given, `compctl` lists all defined completions in
an abbreviated form; with a list of `options`, all completions with
those flags set (not counting extended completion) are listed.
If the `+` flag is alone and followed immediately by the `command` list,
the completion behavior for all the commands in the list is reset to the
default. In other words, completion will subsequently use the options
specified by the `-D` flag.
The form with `-M` as the first and only option defines global matching
specifications (see [Completion Matching
Control](Completion-Widgets.html#Completion-Matching-Control)). The
match specifications given will be used for every completion attempt
(only when using `compctl`, not with the new completion system) and are
tried in the order in which they are defined until one generates at
least one match. E.g.:
<div class="example">
``` example
compctl -M '' 'm:{a-zA-Z}={A-Za-z}'
```
</div>
This will first try completion without any global match specifications
(the empty string) and, if that generates no matches, will try case
insensitive completion.
-----
<span id="Option-Flags"></span> <span id="Option-Flags-1"></span>
## 21.4 Option Flags
\[ `-fcFBdeaRGovNAIOPZEnbjrzu/12` \]
\[ `-k` `array` \] \[ `-g` `globstring` \] \[ `-s` `subststring` \]
\[ `-K` `function` \]
\[ `-Q` \] \[ `-P` `prefix` \] \[ `-S` `suffix` \]
\[ `-W` `file-prefix` \] \[ `-H` `num pattern` \]
\[ `-q` \] \[ `-X` `explanation` \] \[ `-Y` `explanation` \]
\[ `-y` `func-or-var` \] \[ `-l` `cmd` \] \[ `-h` `cmd` \] \[ `-U` \]
\[ `-t` `continue` \] \[ `-J` `name` \] \[ `-V` `name` \]
\[ `-M` `match-spec` \]
The remaining `options` specify the type of command arguments to look
for during completion. Any combination of these flags may be specified;
the result is a sorted list of all the possibilities. The options are as
follows.
-----
<span id="Simple-Flags"></span> <span id="Simple-Flags-1"></span>
### 21.4.1 Simple Flags
These produce completion lists made up by the shell itself:
- `-f`
Filenames and file system paths.
- `-/`
Just file system paths.
- `-c`
Command names, including aliases, shell functions, builtins and
reserved words.
- `-F`
Function names.
- `-B`
Names of builtin commands.
- `-m`
Names of external commands.
- `-w`
Reserved words.
- `-a`
Alias names.
- `-R`
Names of regular (non-global) aliases.
- `-G`
Names of global aliases.
- `-d`
This can be combined with `-F`, `-B`, `-w`, `-a`, `-R` and `-G` to
get names of disabled functions, builtins, reserved words or
aliases.
- `-e`
This option (to show enabled commands) is in effect by default, but
may be combined with `-d`; `-de` in combination with `-F`, `-B`,
`-w`, `-a`, `-R` and `-G` will complete names of functions,
builtins, reserved words or aliases whether or not they are
disabled.
- `-o`
Names of shell options (see [Options](Options.html#Options)).
- `-v`
Names of any variable defined in the shell.
- `-N`
Names of scalar (non-array) parameters.
- `-A`
Array names.
- `-I`
Names of integer variables.
- `-O`
Names of read-only variables.
- `-p`
Names of parameters used by the shell (including special
parameters).
- `-Z`
Names of shell special parameters.
- `-E`
Names of environment variables.
- `-n`
Named directories.
- `-b`
Key binding names.
- `-j`
Job names: the first word of the job leaders command line. This is
useful with the `kill` builtin.
- `-r`
Names of running jobs.
- `-z`
Names of suspended jobs.
- `-u`
User names.
-----
<span id="Flags-with-Arguments"></span>
<span id="Flags-with-Arguments-1"></span>
### 21.4.2 Flags with Arguments
These have user supplied arguments to determine how the list of
completions is to be made up:
- `-k` `array`
Names taken from the elements of `$``array` (note that the `$`
does not appear on the command line). Alternatively, the argument
`array` itself may be a set of space- or comma-separated values in
parentheses, in which any delimiter may be escaped with a backslash;
in this case the argument should be quoted. For example,
<div class="example">
``` example
compctl -k "(cputime filesize datasize stacksize
coredumpsize resident descriptors)" limit
```
</div>
- `-g` `globstring`
The `globstring` is expanded using filename globbing; it should be
quoted to protect it from immediate expansion. The resulting
filenames are taken as the possible completions. Use `*(/)`
instead of `*/` for directories. The `fignore` special parameter
is not applied to the resulting files. More than one pattern may be
given separated by blanks. (Note that brace expansion is *not* part
of globbing. Use the syntax `(either|or)` to match alternatives.)
- `-s` `subststring`
The `subststring` is split into words and these words are than
expanded using all shell expansion mechanisms (see
[Expansion](Expansion.html#Expansion)). The resulting words are
taken as possible completions. The `fignore` special parameter is
not applied to the resulting files. Note that `-g` is faster for
filenames.
- `-K` `function`
<span id="index-reply_002c-use-of-2"></span>
Call the given function to get the completions. Unless the name
starts with an underscore, the function is passed two arguments: the
prefix and the suffix of the word on which completion is to be
attempted, in other words those characters before the cursor
position, and those from the cursor position onwards. The whole
command line can be accessed with the `-c` and `-l` flags of the
`read` builtin. The function should set the variable `reply` to an
array containing the completions (one completion per element); note
that `reply` should not be made local to the function. From such a
function the command line can be accessed with the `-c` and `-l`
flags to the `read` builtin. For example,
<div class="example">
``` example
function whoson { reply=(`users`); }
compctl -K whoson talk
```
</div>
completes only logged-on users after `talk`. Note that `whoson`
must return an array, so `reply=users` would be incorrect.
- `-H` `num pattern`
The possible completions are taken from the last `num` history
lines. Only words matching `pattern` are taken. If `num` is zero or
negative the whole history is searched and if `pattern` is the empty
string all words are taken (as with `*`). A typical use is
<div class="example">
``` example
compctl -D -f + -H 0 ''
```
</div>
which forces completion to look back in the history list for a word
if no filename matches.
-----
<span id="Control-Flags"></span> <span id="Control-Flags-1"></span>
### 21.4.3 Control Flags
These do not directly specify types of name to be completed, but
manipulate the options that do:
- `-Q`
This instructs the shell not to quote any metacharacters in the
possible completions. Normally the results of a completion are
inserted into the command line with any metacharacters quoted so
that they are interpreted as normal characters. This is appropriate
for filenames and ordinary strings. However, for special effects,
such as inserting a backquoted expression from a completion array
(`-k`) so that the expression will not be evaluated until the
complete line is executed, this option must be used.
- `-P` `prefix`
The `prefix` is inserted just before the completed string; any
initial part already typed will be completed and the whole `prefix`
ignored for completion purposes. For example,
<div class="example">
``` example
compctl -j -P "%" kill
```
</div>
inserts a % after the kill command and then completes job names.
- `-S` `suffix`
When a completion is found the `suffix` is inserted after the
completed string. In the case of menu completion the suffix is
inserted immediately, but it is still possible to cycle through the
list of completions by repeatedly hitting the same key.
- `-W` `file-prefix`
With directory `file-prefix`: for command, file, directory and
globbing completion (options `-c`, `-f`, `-/`, `-g`), the file
prefix is implicitly added in front of the completion. For example,
<div class="example">
``` example
compctl -/ -W ~/Mail maildirs
```
</div>
completes any subdirectories to any depth beneath the directory
`~/Mail`, although that prefix does not appear on the command line.
The `file-prefix` may also be of the form accepted by the `-k` flag,
i.e. the name of an array or a literal list in parenthesis. In this
case all the directories in the list will be searched for possible
completions.
- `-q`
If used with a suffix as specified by the `-S` option, this causes
the suffix to be removed if the next character typed is a blank or
does not insert anything or if the suffix consists of only one
character and the next character typed is the same character; this
the same rule used for the `AUTO_REMOVE_SLASH` option. The option is
most useful for list separators (comma, colon, etc.).
- `-l` `cmd`
This option restricts the range of command line words that are
considered to be arguments. If combined with one of the extended
completion patterns `p[`...`]`, `r[`...`]`, or `R[`...`]` (see
[Extended Completion](#Extended-Completion) below) the range is
restricted to the range of arguments specified in the brackets.
Completion is then performed as if these had been given as arguments
to the `cmd` supplied with the option. If the `cmd` string is empty
the first word in the range is instead taken as the command name,
and command name completion performed on the first word in the
range. For example,
<div class="example">
``` example
compctl -x 'r[-exec,;]' -l '' -- find
```
</div>
completes arguments between `-exec` and the following `;` (or
the end of the command line if there is no such string) as if they
were a separate command line.
- `-h` `cmd`
Normally zsh completes quoted strings as a whole. With this option,
completion can be done separately on different parts of such
strings. It works like the `-l` option but makes the completion code
work on the parts of the current word that are separated by spaces.
These parts are completed as if they were arguments to the given
`cmd`. If `cmd` is the empty string, the first part is completed as
a command name, as with `-l`.
- `-U`
Use the whole list of possible completions, whether or not they
actually match the word on the command line. The word typed so far
will be deleted. This is most useful with a function (given by the
`-K` option) which can examine the word components passed to it (or
via the `read` builtins `-c` and `-l` flags) and use its own
criteria to decide what matches. If there is no completion, the
original word is retained. Since the produced possible completions
seldom have interesting common prefixes and suffixes, menu
completion is started immediately if `AUTO_MENU` is set and this
flag is used.
- `-y` `func-or-var`
<span id="index-reply_002c-use-of-3"></span>
The list provided by `func-or-var` is displayed instead of the list
of completions whenever a listing is required; the actual
completions to be inserted are not affected. It can be provided in
two ways. Firstly, if `func-or-var` begins with a `$` it defines a
variable, or if it begins with a left parenthesis a literal array,
which contains the list. A variable may have been set by a call to a
function using the `-K` option. Otherwise it contains the name of a
function which will be executed to create the list. The function
will be passed as an argument list all matching completions,
including prefixes and suffixes expanded in full, and should set the
array `reply` to the result. In both cases, the display list will
only be retrieved after a complete list of matches has been created.
Note that the returned list does not have to correspond, even in
length, to the original set of matches, and may be passed as a
scalar instead of an array. No special formatting of characters is
performed on the output in this case; in particular, newlines are
printed literally and if they appear output in columns is
suppressed.
- `-X` `explanation`
Print `explanation` when trying completion on the current set of
options. A `%n` in this string is replaced by the number of
matches that were added for this explanation string. The explanation
only appears if completion was tried and there was no unique match,
or when listing completions. Explanation strings will be listed
together with the matches of the group specified together with the
`-X` option (using the `-J` or `-V` option). If the same explanation
string is given to multiple `-X` options, the string appears only
once (for each group) and the number of matches shown for the `%n`
is the total number of all matches for each of these uses. In any
case, the explanation string will only be shown if there was at
least one match added for the explanation string.
The sequences `%B`, `%b`, `%S`, `%s`, `%U`, and `%u` specify output
attributes (bold, standout, and underline), `%F`, `%f`, `%K`, `%k`
specify foreground and background colours, and `%{``...``%}` can be
used to include literal escape sequences as in prompts.
- `-Y` `explanation`
Identical to `-X`, except that the `explanation` first undergoes
expansion following the usual rules for strings in double quotes.
The expansion will be carried out after any functions are called for
the `-K` or `-y` options, allowing them to set variables.
- `-t` `continue`
The `continue`-string contains a character that specifies which set
of completion flags should be used next. It is useful:
(i) With `-T`, or when trying a list of pattern completions, when
`compctl` would usually continue with ordinary processing after
finding matches; this can be suppressed with `-tn`.
(ii) With a list of alternatives separated by `+`, when `compctl`
would normally stop when one of the alternatives generates matches.
It can be forced to consider the next set of completions by adding
`-t+` to the flags of the alternative before the `+`.
(iii) In an extended completion list (see below), when `compctl`
would normally continue until a set of conditions succeeded, then
use only the immediately following flags. With `-t-`, `compctl`
will continue trying extended completions after the next `-`; with
`-tx` it will attempt completion with the default flags, in other
words those before the `-x`.
- `-J` `name`
This gives the name of the group the matches should be placed in.
Groups are listed and sorted separately; likewise, menu completion
will offer the matches in the groups in the order in which the
groups were defined. If no group name is explicitly given, the
matches are stored in a group named `default`. The first time a
group name is encountered, a group with that name is created. After
that all matches with the same group name are stored in that group.
This can be useful with non-exclusive alternative completions. For
example, in
<div class="example">
``` example
compctl -f -J files -t+ + -v -J variables foo
```
</div>
both files and variables are possible completions, as the `-t+`
forces both sets of alternatives before and after the `+` to be
considered at once. Because of the `-J` options, however, all files
are listed before all variables.
- `-V` `name`
Like `-J`, but matches within the group will not be sorted in
listings nor in menu completion. These unsorted groups are in a
different name space from the sorted ones, so groups defined as `-J
files` and `-V files` are distinct.
- `-1`
If given together with the `-V` option, makes only consecutive
duplicates in the group be removed. Note that groups with and
without this flag are in different name spaces.
- `-2`
If given together with the `-J` or `-V` option, makes all duplicates
be kept. Again, groups with and without this flag are in different
name spaces.
- `-M` `match-spec`
This defines additional matching control specifications that should
be used only when testing words for the list of flags this flag
appears in. The format of the `match-spec` string is described in
[Completion Matching
Control](Completion-Widgets.html#Completion-Matching-Control).
-----
<span id="Alternative-Completion"></span>
<span id="Alternative-Completion-1"></span>
## 21.5 Alternative Completion
`compctl` \[ `-CDT` \] `options` `+` `options` \[ `+` ... \] \[ `+` \]
`command` ...
The form with `+` specifies alternative options. Completion is tried
with the options before the first `+`. If this produces no matches
completion is tried with the flags after the `+` and so on. If there
are no flags after the last `+` and a match has not been found up to
that point, default completion is tried. If the list of flags contains a
`-t` with a `+` character, the next list of flags is used even if the
current list produced matches.
-----
<span id="Extended-Completion"></span>
Additional options are available that restrict completion to some part
of the command line; this is referred to as extended completion.
<span id="Extended-Completion-1"></span>
## 21.6 Extended Completion
` compctl `\[ `-CDT` \] `options` `-x` `pattern` `options` `-` ...
`-``-`
`        `\[ `command` ... \]
` compctl `\[ `-CDT` \] `options` \[ `-x` `pattern` `options` `-` ...
`-``-` \]
`        `\[ `+` `options` \[ `-x` ... `-``-` \] ... \[`+`\] \] \[
`command` ... \]
The form with `-x` specifies extended completion for the commands
given; as shown, it may be combined with alternative completion using
`+`. Each `pattern` is examined in turn; when a match is found, the
corresponding `options`, as described in [Option Flags](#Option-Flags)
above, are used to generate possible completions. If no `pattern`
matches, the `options` given before the `-x` are used.
Note that each pattern should be supplied as a single argument and
should be quoted to prevent expansion of metacharacters by the shell.
A `pattern` is built of sub-patterns separated by commas; it matches if
at least one of these sub-patterns matches (they are ored). These
sub-patterns are in turn composed of other sub-patterns separated by
white spaces which match if all of the sub-patterns match (they are
anded). An element of the sub-patterns is of the form
`c``[`...`][`...`]`, where the pairs of brackets may be repeated as
often as necessary, and matches if any of the sets of brackets match (an
or). The example below makes this clearer.
The elements may be any of the following:
- `s[``string``]`...
Matches if the current word on the command line starts with one of
the strings given in brackets. The `string` is not removed and is
not part of the completion.
- `S[``string``]`...
Like `s[``string``]` except that the `string` is part of the
completion.
- `p[``from``,``to``]`...
Matches if the number of the current word is between one of the
`from` and `to` pairs inclusive. The comma and `to` are optional;
`to` defaults to the same value as `from`. The numbers may be
negative: `-``n` refers to the `n`th last word on the line.
- `c[``offset``,``string``]`...
Matches if the `string` matches the word offset by `offset` from the
current word position. Usually `offset` will be negative.
- `C[``offset``,``pattern``]`...
Like `c` but using pattern matching instead.
- `w[``index``,``string``]`...
Matches if the word in position `index` is equal to the
corresponding `string`. Note that the word count is made after any
alias expansion.
- `W[``index``,``pattern``]`...
Like `w` but using pattern matching instead.
- `n[``index``,``string``]`...
Matches if the current word contains `string`. Anything up to and
including the `index`th occurrence of this string will not be
considered part of the completion, but the rest will. `index` may be
negative to count from the end: in most cases, `index` will be 1 or
-1. For example,
<div class="example">
``` example
compctl -s '`users`' -x 'n[1,@]' -k hosts -- talk
```
</div>
will usually complete usernames, but if you insert an `@` after the
name, names from the array `hosts` (assumed to contain hostnames,
though you must make the array yourself) will be completed. Other
commands such as `rcp` can be handled similarly.
- `N[``index``,``string``]`...
Like `n` except that the string will be taken as a character class.
Anything up to and including the `index`th occurrence of any of the
characters in `string` will not be considered part of the
completion.
- `m[``min``,``max``]`...
Matches if the total number of words lies between `min` and `max`
inclusive.
- `r[``str1``,``str2``]`...
Matches if the cursor is after a word with prefix `str1`. If there
is also a word with prefix `str2` on the command line after the one
matched by `str1` it matches only if the cursor is before this word.
If the comma and `str2` are omitted, it matches if the cursor is
after a word with prefix `str1`.
- `R[``str1``,``str2``]`...
Like `r` but using pattern matching instead.
- `q[``str``]`...
Matches the word currently being completed is in single quotes and
the `str` begins with the letter s, or if completion is done in
double quotes and `str` starts with the letter d, or if completion
is done in backticks and `str` starts with a b.
-----
<span id="Example"></span> <span id="Example-3"></span>
## 21.7 Example
<div class="example">
``` example
compctl -u -x 's[+] c[-1,-f],s[-f+]' \
-g '~/Mail/*(:t)' - 's[-f],c[-1,-f]' -f -- mail
```
</div>
This is to be interpreted as follows:
If the current command is `mail`, then
> if ((the current word begins with `+` and the previous word is `-f`)
> or (the current word begins with `-f+`)), then complete the
> non-directory part (the `:t` glob modifier) of files in the
> directory `~/Mail`; else
>
> if the current word begins with `-f` or the previous word was `-f`,
> then complete any file; else
>
> complete user names.
-----
This document was generated on *February 15, 2020* using
[*texi2html 5.0*](http://www.nongnu.org/texi2html/).
Zsh version 5.8, released on February 14, 2020.

1339
src/Completion-Widgets.md Normal file

File diff suppressed because it is too large Load Diff

89
src/Concept-Index.md Normal file
View File

@ -0,0 +1,89 @@
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [Concept Index](#concept-index)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<span id="Concept-Index"></span> <span id="Concept-Index-1"></span>
# Concept Index
  [**-**](#Concept-Index-1_cp_symbol-2)  
[**.**](#Concept-Index-1_cp_symbol-3)  
[**A**](#Concept-Index-1_cp_letter-A)  
[**B**](#Concept-Index-1_cp_letter-B)  
[**C**](#Concept-Index-1_cp_letter-C)  
[**D**](zsh_1.html#index_split-0_cp_letter-D)  
[**E**](zsh_1.html#index_split-0_cp_letter-E)  
[**F**](zsh_1.html#index_split-0_cp_letter-F)  
[**G**](zsh_2.html#index_split-1_cp_letter-G)  
[**H**](zsh_2.html#index_split-1_cp_letter-H)  
[**I**](zsh_2.html#index_split-1_cp_letter-I)  
[**J**](zsh_2.html#index_split-1_cp_letter-J)  
[**K**](zsh_2.html#index_split-1_cp_letter-K)  
[**L**](zsh_2.html#index_split-1_cp_letter-L)  
[**M**](zsh_3.html#index_split-2_cp_letter-M)  
[**N**](zsh_3.html#index_split-2_cp_letter-N)  
[**O**](zsh_3.html#index_split-2_cp_letter-O)  
[**P**](zsh_3.html#index_split-2_cp_letter-P)  
[**Q**](zsh_3.html#index_split-2_cp_letter-Q)  
[**R**](zsh_3.html#index_split-2_cp_letter-R)  
[**S**](zsh_4.html#index_split-3_cp_letter-S)  
[**T**](zsh_4.html#index_split-3_cp_letter-T)  
[**U**](zsh_4.html#index_split-3_cp_letter-U)  
[**V**](zsh_4.html#index_split-3_cp_letter-V)  
[**W**](zsh_4.html#index_split-3_cp_letter-W)  
[**Z**](zsh_5.html#index_split-4_cp_letter-Z)  
Index Entry
 
Section
<span id="Concept-Index-1_cp_symbol-1">$</span>
<span id="Concept-Index-1_cp_symbol-2">-</span>
<span id="Concept-Index-1_cp_symbol-3">.</span>
<span id="Concept-Index-1_cp_letter-A">A</span>
<span id="Concept-Index-1_cp_letter-B">B</span>
<span id="Concept-Index-1_cp_letter-C">C</span>
  [**-**](#Concept-Index-1_cp_symbol-2)  
[**.**](#Concept-Index-1_cp_symbol-3)  
[**A**](#Concept-Index-1_cp_letter-A)  
[**B**](#Concept-Index-1_cp_letter-B)  
[**C**](#Concept-Index-1_cp_letter-C)  
[**D**](zsh_1.html#index_split-0_cp_letter-D)  
[**E**](zsh_1.html#index_split-0_cp_letter-E)  
[**F**](zsh_1.html#index_split-0_cp_letter-F)  
[**G**](zsh_2.html#index_split-1_cp_letter-G)  
[**H**](zsh_2.html#index_split-1_cp_letter-H)  
[**I**](zsh_2.html#index_split-1_cp_letter-I)  
[**J**](zsh_2.html#index_split-1_cp_letter-J)  
[**K**](zsh_2.html#index_split-1_cp_letter-K)  
[**L**](zsh_2.html#index_split-1_cp_letter-L)  
[**M**](zsh_3.html#index_split-2_cp_letter-M)  
[**N**](zsh_3.html#index_split-2_cp_letter-N)  
[**O**](zsh_3.html#index_split-2_cp_letter-O)  
[**P**](zsh_3.html#index_split-2_cp_letter-P)  
[**Q**](zsh_3.html#index_split-2_cp_letter-Q)  
[**R**](zsh_3.html#index_split-2_cp_letter-R)  
[**S**](zsh_4.html#index_split-3_cp_letter-S)  
[**T**](zsh_4.html#index_split-3_cp_letter-T)  
[**U**](zsh_4.html#index_split-3_cp_letter-U)  
[**V**](zsh_4.html#index_split-3_cp_letter-V)  
[**W**](zsh_4.html#index_split-3_cp_letter-W)  
[**Z**](zsh_5.html#index_split-4_cp_letter-Z)  
-----
This document was generated on *February 15, 2020* using
[*texi2html 5.0*](http://www.nongnu.org/texi2html/).
Zsh version 5.8, released on February 14, 2020.

View File

@ -0,0 +1,270 @@
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [12 Conditional Expressions](#12-conditional-expressions)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<span id="Conditional-Expressions"></span>
<span id="Conditional-Expressions-1"></span>
# 12 Conditional Expressions
<span id="index-conditional-expressions"></span>
<span id="index-expressions_002c-conditional"></span>
A *conditional expression* is used with the `[[` compound command to
test attributes of files and to compare strings. Each expression can be
constructed from one or more of the following unary or binary
expressions:
- `-a` `file`
true if `file` exists.
- `-b` `file`
true if `file` exists and is a block special file.
- `-c` `file`
true if `file` exists and is a character special file.
- `-d` `file`
true if `file` exists and is a directory.
- `-e` `file`
true if `file` exists.
- `-f` `file`
true if `file` exists and is a regular file.
- `-g` `file`
true if `file` exists and has its setgid bit set.
- `-h` `file`
true if `file` exists and is a symbolic link.
- `-k` `file`
true if `file` exists and has its sticky bit set.
- `-n` `string`
true if length of `string` is non-zero.
- `-o` `option`
true if option named `option` is on. `option` may be a single
character, in which case it is a single letter option name. (See
[Specifying Options](Options.html#Specifying-Options).)
When no option named `option` exists, and the `POSIX_BUILTINS`
option hasnt been set, return 3 with a warning. If that option is
set, return 1 with no warning.
- `-p` `file`
true if `file` exists and is a FIFO special file (named pipe).
- `-r` `file`
true if `file` exists and is readable by current process.
- `-s` `file`
true if `file` exists and has size greater than zero.
- `-t` `fd`
true if file descriptor number `fd` is open and associated with a
terminal device. (note: `fd` is not optional)
- `-u` `file`
true if `file` exists and has its setuid bit set.
- `-v` `varname`
true if shell variable `varname` is set.
- `-w` `file`
`-x` `file`
`-z` `string`
true if length of `string` is zero.
- `-L` `file`
true if `file` exists and is a symbolic link.
- `-O` `file`
true if `file` exists and is owned by the effective user ID of this
process.
- `-G` `file`
true if `file` exists and its group matches the effective group ID
of this process.
- `-S` `file`
true if `file` exists and is a socket.
- `-N` `file`
true if `file` exists and its access time is not newer than its
modification time.
- `file1` `-nt` `file2`
true if `file1` exists and is newer than `file2`.
- `file1` `-ot` `file2`
true if `file1` exists and is older than `file2`.
- `file1` `-ef` `file2`
true if `file1` and `file2` exist and refer to the same file.
- `string` `=` `pattern`
`string` `==` `pattern`
true if `string` matches `pattern`. The two forms are exactly
equivalent. The `=` form is the traditional shell syntax (and
hence the only one generally used with the `test` and `[` builtins);
the `==` form provides compatibility with other sorts of computer
language.
- `string` `!=` `pattern`
true if `string` does not match `pattern`.
- `string` `=~` `regexp`
true if `string` matches the regular expression `regexp`. If the
option `RE_MATCH_PCRE` is set `regexp` is tested as a PCRE regular
expression using the `zsh/pcre` module, else it is tested as a POSIX
extended regular expression using the `zsh/regex` module. Upon
successful match, some variables will be updated; no variables are
changed if the matching fails.
If the option `BASH_REMATCH` is not set the scalar parameter `MATCH`
is set to the substring that matched the pattern and the integer
parameters `MBEGIN` and `MEND` to the index of the start and end,
respectively, of the match in `string`, such that if `string` is
contained in variable `var` the expression `${var[$MBEGIN,$MEND]}`
is identical to `$MATCH`. The setting of the option `KSH_ARRAYS`
is respected. Likewise, the array `match` is set to the substrings
that matched parenthesised subexpressions and the arrays `mbegin`
and `mend` to the indices of the start and end positions,
respectively, of the substrings within `string`. The arrays are not
set if there were no parenthesised subexpressions. For example, if
the string `a short string` is matched against the regular
expression `s(...)t`, then (assuming the option `KSH_ARRAYS` is
not set) `MATCH`, `MBEGIN` and `MEND` are `short`, `3` and `7`,
respectively, while `match`, `mbegin` and `mend` are single entry
arrays containing the strings `hor`, `4` and `6`,
respectively.
If the option `BASH_REMATCH` is set the array `BASH_REMATCH` is set
to the substring that matched the pattern followed by the substrings
that matched parenthesised subexpressions within the pattern.
- `string1` `<` `string2`
true if `string1` comes before `string2` based on ASCII value of
their characters.
- `string1` `>` `string2`
true if `string1` comes after `string2` based on ASCII value of
their characters.
- `exp1` `-eq` `exp2`
true if `exp1` is numerically equal to `exp2`. Note that for purely
numeric comparisons use of the `((``...``))` builtin described in
[Arithmetic
Evaluation](Arithmetic-Evaluation.html#Arithmetic-Evaluation) is
more convenient than conditional expressions.
- `exp1` `-ne` `exp2`
true if `exp1` is numerically not equal to `exp2`.
- `exp1` `-lt` `exp2`
true if `exp1` is numerically less than `exp2`.
- `exp1` `-gt` `exp2`
true if `exp1` is numerically greater than `exp2`.
- `exp1` `-le` `exp2`
true if `exp1` is numerically less than or equal to `exp2`.
- `exp1` `-ge` `exp2`
true if `exp1` is numerically greater than or equal to `exp2`.
- `(` `exp` `)`
true if `exp` is true.
- `!` `exp`
true if `exp` is false.
- `exp1` `&&` `exp2`
true if `exp1` and `exp2` are both true.
- `exp1` `||` `exp2`
true if either `exp1` or `exp2` is true.
For compatibility, if there is a single argument that is not
syntactically significant, typically a variable, the condition is
treated as a test for whether the expression expands as a string of
non-zero length. In other words, `[[ $var ]]` is the same as `[[ -n $var
]]`. It is recommended that the second, explicit, form be used where
possible.
Normal shell expansion is performed on the `file`, `string` and
`pattern` arguments, but the result of each expansion is constrained to
be a single word, similar to the effect of double quotes.
Filename generation is not performed on any form of argument to
conditions. However, it can be forced in any case where normal shell
expansion is valid and when the option `EXTENDED_GLOB` is in effect by
using an explicit glob qualifier of the form `(#q)` at the end of the
string. A normal glob qualifier expression may appear between the `q`
and the closing parenthesis; if none appears the expression has no
effect beyond causing filename generation. The results of filename
generation are joined together to form a single word, as with the
results of other forms of expansion.
This special use of filename generation is only available with the `[[`
syntax. If the condition occurs within the `[` or `test` builtin
commands then globbing occurs instead as part of normal command line
expansion before the condition is evaluated. In this case it may
generate multiple words which are likely to confuse the syntax of the
test command.
For example,
<div class="example">
``` example
[[ -n file*(#qN) ]]
```
</div>
produces status zero if and only if there is at least one file in the
current directory beginning with the string `file`. The globbing
qualifier `N` ensures that the expression is empty if there is no
matching file.
Pattern metacharacters are active for the `pattern` arguments; the
patterns are the same as those used for filename generation, see
[Filename Generation](Expansion.html#Filename-Generation), but there is
no special behaviour of `/` nor initial dots, and no glob qualifiers
are allowed.
In each of the above expressions, if `file` is of the form
`/dev/fd/``n`, where `n` is an integer, then the test applied to the
open file whose descriptor number is `n`, even if the underlying system
does not support the `/dev/fd` directory.
In the forms which do numeric comparison, the expressions `exp` undergo
arithmetic expansion as if they were enclosed in `$((``...``))`.
For example, the following:
<div class="example">
``` example
[[ ( -f foo || -f bar ) && $report = y* ]] && print File exists.
```
</div>
tests if either file `foo` or file `bar` exists, and if so, if the value
of the parameter `report` begins with `y`; if the complete condition
is true, the message `File exists.` is printed.
-----
This document was generated on *February 15, 2020* using
[*texi2html 5.0*](http://www.nongnu.org/texi2html/).
Zsh version 5.8, released on February 14, 2020.

View File

@ -0,0 +1,96 @@
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [Editor Functions Index](#editor-functions-index)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<span id="Editor-Functions-Index"></span>
<span id="Editor-Functions-Index-1"></span>
# Editor Functions Index
  [**B**](#Editor-Functions-Index-1_tp_letter-B)  
[**C**](#Editor-Functions-Index-1_tp_letter-C)  
[**D**](#Editor-Functions-Index-1_tp_letter-D)  
[**E**](#Editor-Functions-Index-1_tp_letter-E)  
[**F**](#Editor-Functions-Index-1_tp_letter-F)  
[**G**](#Editor-Functions-Index-1_tp_letter-G)  
[**H**](#Editor-Functions-Index-1_tp_letter-H)  
[**I**](#Editor-Functions-Index-1_tp_letter-I)  
[**K**](#Editor-Functions-Index-1_tp_letter-K)  
[**L**](#Editor-Functions-Index-1_tp_letter-L)  
[**M**](#Editor-Functions-Index-1_tp_letter-M)  
[**N**](zsh_16.html#index_split-15_tp_letter-N)  
[**O**](zsh_16.html#index_split-15_tp_letter-O)  
[**P**](zsh_16.html#index_split-15_tp_letter-P)  
[**Q**](zsh_16.html#index_split-15_tp_letter-Q)  
[**R**](zsh_16.html#index_split-15_tp_letter-R)  
[**S**](zsh_16.html#index_split-15_tp_letter-S)  
[**T**](zsh_16.html#index_split-15_tp_letter-T)  
[**U**](zsh_16.html#index_split-15_tp_letter-U)  
[**V**](zsh_16.html#index_split-15_tp_letter-V)  
[**W**](zsh_17.html#index_split-16_tp_letter-W)  
[**Y**](zsh_17.html#index_split-16_tp_letter-Y)  
[**Z**](zsh_17.html#index_split-16_tp_letter-Z)  
Index Entry
 
Section
<span id="Editor-Functions-Index-1_tp_letter-A">A</span>
<span id="Editor-Functions-Index-1_tp_letter-B">B</span>
<span id="Editor-Functions-Index-1_tp_letter-C">C</span>
<span id="Editor-Functions-Index-1_tp_letter-D">D</span>
<span id="Editor-Functions-Index-1_tp_letter-E">E</span>
<span id="Editor-Functions-Index-1_tp_letter-F">F</span>
<span id="Editor-Functions-Index-1_tp_letter-G">G</span>
<span id="Editor-Functions-Index-1_tp_letter-H">H</span>
<span id="Editor-Functions-Index-1_tp_letter-I">I</span>
<span id="Editor-Functions-Index-1_tp_letter-K">K</span>
<span id="Editor-Functions-Index-1_tp_letter-L">L</span>
<span id="Editor-Functions-Index-1_tp_letter-M">M</span>
  [**B**](#Editor-Functions-Index-1_tp_letter-B)  
[**C**](#Editor-Functions-Index-1_tp_letter-C)  
[**D**](#Editor-Functions-Index-1_tp_letter-D)  
[**E**](#Editor-Functions-Index-1_tp_letter-E)  
[**F**](#Editor-Functions-Index-1_tp_letter-F)  
[**G**](#Editor-Functions-Index-1_tp_letter-G)  
[**H**](#Editor-Functions-Index-1_tp_letter-H)  
[**I**](#Editor-Functions-Index-1_tp_letter-I)  
[**K**](#Editor-Functions-Index-1_tp_letter-K)  
[**L**](#Editor-Functions-Index-1_tp_letter-L)  
[**M**](#Editor-Functions-Index-1_tp_letter-M)  
[**N**](zsh_16.html#index_split-15_tp_letter-N)  
[**O**](zsh_16.html#index_split-15_tp_letter-O)  
[**P**](zsh_16.html#index_split-15_tp_letter-P)  
[**Q**](zsh_16.html#index_split-15_tp_letter-Q)  
[**R**](zsh_16.html#index_split-15_tp_letter-R)  
[**S**](zsh_16.html#index_split-15_tp_letter-S)  
[**T**](zsh_16.html#index_split-15_tp_letter-T)  
[**U**](zsh_16.html#index_split-15_tp_letter-U)  
[**V**](zsh_16.html#index_split-15_tp_letter-V)  
[**W**](zsh_17.html#index_split-16_tp_letter-W)  
[**Y**](zsh_17.html#index_split-16_tp_letter-Y)  
[**Z**](zsh_17.html#index_split-16_tp_letter-Z)  
-----
This document was generated on *February 15, 2020* using
[*texi2html 5.0*](http://www.nongnu.org/texi2html/).
Zsh version 5.8, released on February 14, 2020.

3226
src/Expansion.md Normal file

File diff suppressed because it is too large Load Diff

116
src/Files.md Normal file
View File

@ -0,0 +1,116 @@
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [5 Files](#5-files)
- [5.1 Startup/Shutdown Files](#51-startupshutdown-files)
- [5.2 Files](#52-files)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<span id="Files"></span> <span id="Files-1"></span>
# 5 Files
-----
<span id="Startup_002fShutdown-Files"></span>
## 5.1 Startup/Shutdown Files
<span id="index-files_002c-startup"></span>
<span id="index-startup-files"></span>
<span id="index-files_002c-shutdown"></span>
<span id="index-shutdown-files"></span>
<span id="index-RCS_002c-use-of"></span>
<span id="index-GLOBAL_005fRCS_002c-use-of"></span>
<span id="index-NO_005fRCS_002c-use-of"></span>
<span id="index-NO_005fGLOBAL_005fRCS_002c-use-of"></span>
<span id="index-ZDOTDIR_002c-use-of"></span>
<span id="index-zshenv"></span>
Commands are first read from `/etc/zshenv`; this cannot be overridden.
Subsequent behaviour is modified by the `RCS` and `GLOBAL_RCS` options;
the former affects all startup files, while the second only affects
global startup files (those shown here with an path starting with a
`/`). If one of the options is unset at any point, any subsequent
startup file(s) of the corresponding type will not be read. It is also
possible for a file in `$ZDOTDIR` to re-enable `GLOBAL_RCS`. Both `RCS`
and `GLOBAL_RCS` are set by default.
Commands are then read from `$ZDOTDIR/.zshenv`.
<span id="index-LOGIN_002c-use-of"></span>
<span id="index-zprofile"></span> If the shell is a login shell,
commands are read from `/etc/zprofile` and then `$ZDOTDIR/.zprofile`.
<span id="index-zshrc"></span> Then, if the shell is interactive,
commands are read from `/etc/zshrc` and then `$ZDOTDIR/.zshrc`.
<span id="index-zlogin"></span> Finally, if the shell is a login shell,
`/etc/zlogin` and `$ZDOTDIR/.zlogin` are read.
<span id="index-zlogout"></span>
When a login shell exits, the files `$ZDOTDIR/.zlogout` and then
`/etc/zlogout` are read. This happens with either an explicit exit via
the `exit` or `logout` commands, or an implicit exit by reading
end-of-file from the terminal. However, if the shell terminates due to
`exec`ing another process, the logout files are not read. These are
also affected by the `RCS` and `GLOBAL_RCS` options. Note also that the
`RCS` option affects the saving of history files, i.e. if `RCS` is unset
when the shell exits, no history file will be saved.
<span id="index-HOME_002c-use-of"></span>
If `ZDOTDIR` is unset, `HOME` is used instead. Files listed above as
being in `/etc` may be in another directory, depending on the
installation.
As `/etc/zshenv` is run for all instances of zsh, it is important that
it be kept as small as possible. In particular, it is a good idea to put
code that does not need to be run for every single shell behind a test
of the form `if [[ -o rcs ]]; then ...` so that it will not be
executed when zsh is invoked with the `-f` option.
-----
<span id="Files-2"></span>
## 5.2 Files
<span id="index-files-used"></span>
`$ZDOTDIR/.zshenv`
`$ZDOTDIR/.zprofile`
`$ZDOTDIR/.zshrc`
`$ZDOTDIR/.zlogin`
`$ZDOTDIR/.zlogout`
`${TMPPREFIX}*` (default is /tmp/zsh\*)
`/etc/zshenv`
`/etc/zprofile`
`/etc/zshrc`
`/etc/zlogin`
`/etc/zlogout` (installation-specific - `/etc` is the default)
Any of these files may be pre-compiled with the `zcompile` builtin
command ([Shell Builtin
Commands](Shell-Builtin-Commands.html#Shell-Builtin-Commands)). If a
compiled file exists (named for the original file plus the `.zwc`
extension) and it is newer than the original file, the compiled file
will be used instead.
-----
This document was generated on *February 15, 2020* using
[*texi2html 5.0*](http://www.nongnu.org/texi2html/).
Zsh version 5.8, released on February 14, 2020.

91
src/Functions-Index.md Normal file
View File

@ -0,0 +1,91 @@
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [Functions Index](#functions-index)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<span id="Functions-Index"></span> <span id="Functions-Index-1"></span>
# Functions Index
  [**.**](#Functions-Index-1_fn_symbol-2)  
[**:**](#Functions-Index-1_fn_symbol-3)  
[**\[**](#Functions-Index-1_fn_symbol-4)  
[**\_**](#Functions-Index-1_fn_symbol-5)  
[**A**](#Functions-Index-1_fn_letter-A)  
[**B**](#Functions-Index-1_fn_letter-B)  
[**C**](zsh_13.html#index_split-12_fn_letter-C)  
[**D**](zsh_13.html#index_split-12_fn_letter-D)  
[**E**](zsh_13.html#index_split-12_fn_letter-E)  
[**F**](zsh_13.html#index_split-12_fn_letter-F)  
[**G**](zsh_13.html#index_split-12_fn_letter-G)  
[**H**](zsh_13.html#index_split-12_fn_letter-H)  
[**I**](zsh_13.html#index_split-12_fn_letter-I)  
[**J**](zsh_13.html#index_split-12_fn_letter-J)  
[**K**](zsh_13.html#index_split-12_fn_letter-K)  
[**L**](zsh_13.html#index_split-12_fn_letter-L)  
[**M**](zsh_13.html#index_split-12_fn_letter-M)  
[**N**](zsh_13.html#index_split-12_fn_letter-N)  
[**P**](zsh_14.html#index_split-13_fn_letter-P)  
[**R**](zsh_14.html#index_split-13_fn_letter-R)  
[**S**](zsh_14.html#index_split-13_fn_letter-S)  
[**T**](zsh_14.html#index_split-13_fn_letter-T)  
[**U**](zsh_14.html#index_split-13_fn_letter-U)  
[**V**](zsh_15.html#index_split-14_fn_letter-V)  
[**W**](zsh_15.html#index_split-14_fn_letter-W)  
[**Z**](zsh_15.html#index_split-14_fn_letter-Z)  
Index Entry
 
Section
<span id="Functions-Index-1_fn_symbol-1">-</span>
<span id="Functions-Index-1_fn_symbol-2">.</span>
<span id="Functions-Index-1_fn_symbol-3">:</span>
<span id="Functions-Index-1_fn_symbol-4">\[</span>
<span id="Functions-Index-1_fn_symbol-5">\_</span>
<span id="Functions-Index-1_fn_letter-A">A</span>
<span id="Functions-Index-1_fn_letter-B">B</span>
  [**.**](#Functions-Index-1_fn_symbol-2)  
[**:**](#Functions-Index-1_fn_symbol-3)  
[**\[**](#Functions-Index-1_fn_symbol-4)  
[**\_**](#Functions-Index-1_fn_symbol-5)  
[**A**](#Functions-Index-1_fn_letter-A)  
[**B**](#Functions-Index-1_fn_letter-B)  
[**C**](zsh_13.html#index_split-12_fn_letter-C)  
[**D**](zsh_13.html#index_split-12_fn_letter-D)  
[**E**](zsh_13.html#index_split-12_fn_letter-E)  
[**F**](zsh_13.html#index_split-12_fn_letter-F)  
[**G**](zsh_13.html#index_split-12_fn_letter-G)  
[**H**](zsh_13.html#index_split-12_fn_letter-H)  
[**I**](zsh_13.html#index_split-12_fn_letter-I)  
[**J**](zsh_13.html#index_split-12_fn_letter-J)  
[**K**](zsh_13.html#index_split-12_fn_letter-K)  
[**L**](zsh_13.html#index_split-12_fn_letter-L)  
[**M**](zsh_13.html#index_split-12_fn_letter-M)  
[**N**](zsh_13.html#index_split-12_fn_letter-N)  
[**P**](zsh_14.html#index_split-13_fn_letter-P)  
[**R**](zsh_14.html#index_split-13_fn_letter-R)  
[**S**](zsh_14.html#index_split-13_fn_letter-S)  
[**T**](zsh_14.html#index_split-13_fn_letter-T)  
[**U**](zsh_14.html#index_split-13_fn_letter-U)  
[**V**](zsh_15.html#index_split-14_fn_letter-V)  
[**W**](zsh_15.html#index_split-14_fn_letter-W)  
[**Z**](zsh_15.html#index_split-14_fn_letter-Z)  
-----
This document was generated on *February 15, 2020* using
[*texi2html 5.0*](http://www.nongnu.org/texi2html/).
Zsh version 5.8, released on February 14, 2020.

522
src/Functions.md Normal file
View File

@ -0,0 +1,522 @@
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [9 Functions](#9-functions)
- [9.1 Autoloading Functions](#91-autoloading-functions)
- [9.2 Anonymous Functions](#92-anonymous-functions)
- [9.3 Special Functions](#93-special-functions)
- [9.3.1 Hook Functions](#931-hook-functions)
- [9.3.2 Trap Functions](#932-trap-functions)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<span id="Functions"></span> <span id="Functions-3"></span>
# 9 Functions
<span id="index-functions"></span>
<span id="index-function_002c-use-of"></span>
Shell functions are defined with the `function` reserved word or the
special syntax `funcname` `()`. Shell functions are read in and stored
internally. Alias names are resolved when the function is read.
Functions are executed like commands with the arguments passed as
positional parameters. (See [Command
Execution](Command-Execution.html#Command-Execution).)
Functions execute in the same process as the caller and share all files
and present working directory with the caller. A trap on `EXIT` set
inside a function is executed after the function completes in the
environment of the caller.
<span id="index-return_002c-use-of"></span>
The `return` builtin is used to return from function calls.
<span id="index-functions_002c-use-of"></span>
Function identifiers can be listed with the `functions` builtin.
<span id="index-unfunction_002c-use-of"></span> Functions can be
undefined with the `unfunction` builtin.
-----
<span id="Autoloading-Functions"></span>
## 9.1 Autoloading Functions
<span id="index-autoloading-functions"></span>
<span id="index-functions_002c-autoloading"></span>
<span id="index-autoload_002c-use-of"></span>
<span id="index-fpath_002c-use-of"></span>
A function can be marked as *undefined* using the `autoload` builtin (or
`functions -u` or `typeset -fu`). Such a function has no body. When
the function is first executed, the shell searches for its definition
using the elements of the `fpath` variable. Thus to define functions for
autoloading, a typical sequence is:
<div class="example">
``` example
fpath=(~/myfuncs $fpath)
autoload myfunc1 myfunc2 ...
```
</div>
The usual alias expansion during reading will be suppressed if the
`autoload` builtin or its equivalent is given the option `-U`. This is
recommended for the use of functions supplied with the zsh distribution.
<span id="index-zcompile_002c-use-of"></span> Note that for functions
precompiled with the `zcompile` builtin command the flag `-U` must be
provided when the `.zwc` file is created, as the corresponding
information is compiled into the latter.
For each `element` in `fpath`, the shell looks for three possible files,
the newest of which is used to load the definition for the function:
- `element``.zwc`
A file created with the `zcompile` builtin command, which is
expected to contain the definitions for all functions in the
directory named `element`. The file is treated in the same manner as
a directory containing files for functions and is searched for the
definition of the function. If the definition is not found, the
search for a definition proceeds with the other two possibilities
described below.
If `element` already includes a `.zwc` extension (i.e. the extension
was explicitly given by the user), `element` is searched for the
definition of the function without comparing its age to that of
other files; in fact, there does not need to be any directory named
`element` without the suffix. Thus including an element such as
`/usr/local/funcs.zwc` in `fpath` will speed up the search for
functions, with the disadvantage that functions included must be
explicitly recompiled by hand before the shell notices any changes.
- `element``/``function``.zwc`
A file created with `zcompile`, which is expected to contain the
definition for `function`. It may include other function definitions
as well, but those are neither loaded nor executed; a file found in
this way is searched *only* for the definition of `function`.
- `element``/``function`
A file of zsh command text, taken to be the definition for
`function`.
In summary, the order of searching is, first, in the *parents of*
directories in `fpath` for the newer of either a compiled directory or a
directory in `fpath`; second, if more than one of these contains a
definition for the function that is sought, the leftmost in the `fpath`
is chosen; and third, within a directory, the newer of either a compiled
function or an ordinary function definition is used.
<span id="index-KSH_005fAUTOLOAD_002c-use-of"></span>
If the `KSH_AUTOLOAD` option is set, or the file contains only a simple
definition of the function, the files contents will be executed. This
will normally define the function in question, but may also perform
initialization, which is executed in the context of the function
execution, and may therefore define local parameters. It is an error if
the function is not defined by loading the file.
Otherwise, the function body (with no surrounding `funcname``()
{``...``}`) is taken to be the complete contents of the file. This
processing of the file results in the function being re-defined, the
function itself is not re-executed. To force the shell to perform
initialization and then call the function defined, the file should
contain initialization code (which will be executed then discarded) in
addition to a complete function definition (which will be retained for
subsequent calls to the function), and a call to the shell function,
including any arguments, at the end.
For example, suppose the autoload file `func` contains
<div class="example">
``` example
func() { print This is func; }
print func is initialized
```
</div>
then `func; func` with `KSH_AUTOLOAD` set will produce both messages
on the first call, but only the message `This is func` on the second
and subsequent calls. Without `KSH_AUTOLOAD` set, it will produce the
initialization message on the first call, and the other message on the
second and subsequent calls.
It is also possible to create a function that is not marked as
autoloaded, but which loads its own definition by searching `fpath`, by
using `autoload -X` within a shell function. For example, the
following are equivalent:
<div class="example">
``` example
myfunc() {
autoload -X
}
myfunc args...
```
</div>
and
<div class="example">
``` example
unfunction myfunc # if myfunc was defined
autoload myfunc
myfunc args...
```
</div>
In fact, the `functions` command outputs `builtin autoload -X` as the
body of an autoloaded function. This is done so that
<div class="example">
``` example
eval "$(functions)"
```
</div>
produces a reasonable result. A true autoloaded function can be
identified by the presence of the comment `# undefined` in the body,
because all comments are discarded from defined functions.
To load the definition of an autoloaded function `myfunc` without
executing `myfunc`, use:
<div class="example">
``` example
autoload +X myfunc
```
</div>
-----
<span id="Anonymous-Functions"></span>
## 9.2 Anonymous Functions
<span id="index-anonymous-functions"></span>
<span id="index-functions_002c-anonymous"></span>
If no name is given for a function, it is anonymous and is handled
specially. Either form of function definition may be used: a `()` with
no preceding name, or a `function` with an immediately following open
brace. The function is executed immediately at the point of definition
and is not stored for future use. The function name is set to
`(anon)`.
Arguments to the function may be specified as words following the
closing brace defining the function, hence if there are none no
arguments (other than `$0`) are set. This is a difference from the way
other functions are parsed: normal function definitions may be followed
by certain keywords such as `else` or `fi`, which will be treated as
arguments to anonymous functions, so that a newline or semicolon is
needed to force keyword interpretation.
Note also that the argument list of any enclosing script or function is
hidden (as would be the case for any other function called at this
point).
Redirections may be applied to the anonymous function in the same manner
as to a current-shell structure enclosed in braces. The main use of
anonymous functions is to provide a scope for local variables. This is
particularly convenient in start-up files as these do not provide their
own local variable scope.
For example,
<div class="example">
``` example
variable=outside
function {
local variable=inside
print "I am $variable with arguments $*"
} this and that
print "I am $variable"
```
</div>
outputs the following:
<div class="example">
``` example
I am inside with arguments this and that
I am outside
```
</div>
Note that function definitions with arguments that expand to nothing,
for example ` name=; function $name { ``...`` } `, are not treated
as anonymous functions. Instead, they are treated as normal function
definitions where the definition is silently discarded.
-----
<span id="Special-Functions"></span>
## 9.3 Special Functions
Certain functions, if defined, have special meaning to the shell.
-----
<span id="Hook-Functions"></span>
### 9.3.1 Hook Functions
<span id="index-functions_002c-hook"></span>
<span id="index-hook-functions"></span>
For the functions below, it is possible to define an array that has the
same name as the function with `_functions` appended. Any element in
such an array is taken as the name of a function to execute; it is
executed in the same context and with the same arguments as the basic
function. For example, if `$chpwd_functions` is an array containing the
values `mychpwd`, `chpwd_save_dirstack`, then the shell attempts to
execute the functions `chpwd`, `mychpwd` and
`chpwd_save_dirstack`, in that order. Any function that does not
exist is silently ignored. A function found by this mechanism is
referred to elsewhere as a hook function. An error in any function
causes subsequent functions not to be run. Note further that an error in
a `precmd` hook causes an immediately following `periodic` function not
to run (though it may run at the next opportunity).
<span id="index-chpwd"></span>
<span id="index-chpwd_005ffunctions"></span>
`chpwd`
Executed whenever the current working directory is changed.
<span id="index-periodic"></span>
<span id="index-periodic_005ffunctions"></span>
`periodic`
<span id="index-PERIOD"></span>
If the parameter `PERIOD` is set, this function is executed every
`$PERIOD` seconds, just before a prompt. Note that if multiple functions
are defined using the array `periodic_functions` only one period is
applied to the complete set of functions, and the scheduled time is not
reset if the list of functions is altered. Hence the set of functions is
always called together.
<span id="index-precmd"></span>
<span id="index-precmd_005ffunctions"></span>
`precmd`
Executed before each prompt. Note that precommand functions are not
re-executed simply because the command line is redrawn, as happens, for
example, when a notification about an exiting job is displayed.
<span id="index-preexec"></span>
<span id="index-preexec_005ffunctions"></span>
`preexec`
Executed just after a command has been read and is about to be executed.
If the history mechanism is active (regardless of whether the line was
discarded from the history buffer), the string that the user typed is
passed as the first argument, otherwise it is an empty string. The
actual command that will be executed (including expanded aliases) is
passed in two different forms: the second argument is a single-line,
size-limited version of the command (with things like function bodies
elided); the third argument contains the full text that is being
executed.
<span id="index-zshaddhistory"></span>
<span id="index-zshaddhistory_005ffunctions"></span>
`zshaddhistory`
<span id="index-history_002c-hook-when-line-is-saved"></span>
Executed when a history line has been read interactively, but before it
is executed. The sole argument is the complete history line (so that any
terminating newline will still be present).
If any of the hook functions returns status 1 (or any non-zero value
other than 2, though this is not guaranteed for future versions of the
shell) the history line will not be saved, although it lingers in the
history until the next line is executed, allowing you to reuse or edit
it immediately.
If any of the hook functions returns status 2 the history line will be
saved on the internal history list, but not written to the history file.
In case of a conflict, the first non-zero status value is taken.
A hook function may call `fc -p` `...` to switch the history context
so that the history is saved in a different file from the that in the
global `HISTFILE` parameter. This is handled specially: the history
context is automatically restored after the processing of the history
line is finished.
The following example function works with one of the options
`INC_APPEND_HISTORY` or `SHARE_HISTORY` set, in order that the line is
written out immediately after the history entry is added. It first adds
the history line to the normal history with the newline stripped, which
is usually the correct behaviour. Then it switches the history context
so that the line will be written to a history file in the current
directory.
<div class="example">
``` example
zshaddhistory() {
print -sr -- ${1%%$'\n'}
fc -p .zsh_local_history
}
```
</div>
<span id="index-zshexit"></span>
<span id="index-zshexit_005ffunctions"></span>
`zshexit`
Executed at the point where the main shell is about to exit normally.
This is not called by exiting subshells, nor when the `exec` precommand
modifier is used before an external command. Also, unlike `TRAPEXIT`, it
is not called when functions exit.
-----
<span id="Trap-Functions"></span>
### 9.3.2 Trap Functions
The functions below are treated specially but do not have corresponding
hook arrays.
- `TRAP``NAL`
<span id="index-signals_002c-trapping"></span>
<span id="index-trapping-signals"></span>
If defined and non-null, this function will be executed whenever the
shell catches a signal `SIG``NAL`, where `NAL` is a signal name as
specified for the `kill` builtin. The signal number will be passed
as the first parameter to the function.
If a function of this form is defined and null, the shell and
processes spawned by it will ignore `SIG``NAL`.
The return status from the function is handled specially. If it is
zero, the signal is assumed to have been handled, and execution
continues normally. Otherwise, the shell will behave as interrupted
except that the return status of the trap is retained.
Programs terminated by uncaught signals typically return the status
128 plus the signal number. Hence the following causes the handler
for `SIGINT` to print a message, then mimic the usual effect of the
signal.
<div class="example">
``` example
TRAPINT() {
print "Caught SIGINT, aborting."
return $(( 128 + $1 ))
}
```
</div>
The functions `TRAPZERR`, `TRAPDEBUG` and `TRAPEXIT` are never
executed inside other traps.
<span id="index-TRAPDEBUG"></span>
- `TRAPDEBUG`
If the option `DEBUG_BEFORE_CMD` is set (as it is by default),
executed before each command; otherwise executed after each command.
See the description of the `trap` builtin in [Shell Builtin
Commands](Shell-Builtin-Commands.html#Shell-Builtin-Commands) for
details of additional features provided in debug traps.
<span id="index-TRAPEXIT"></span>
- `TRAPEXIT`
Executed when the shell exits, or when the current function exits if
defined inside a function. The value of `$?` at the start of
execution is the exit status of the shell or the return status of
the function exiting.
<span id="index-TRAPZERR"></span> <span id="index-TRAPERR"></span>
- `TRAPZERR`
Executed whenever a command has a non-zero exit status. However, the
function is not executed if the command occurred in a sublist
followed by `&&` or `||`; only the final command in a sublist of
this type causes the trap to be executed. The function `TRAPERR`
acts the same as `TRAPZERR` on systems where there is no `SIGERR`
(this is the usual case).
<span id="index-trap_002c-use-of"></span>
The functions beginning `TRAP` may alternatively be defined with the
`trap` builtin: this may be preferable for some uses. Setting a trap
with one form removes any trap of the other form for the same signal;
removing a trap in either form removes all traps for the same signal.
The forms
<div class="example">
``` example
TRAPNAL() {
# code
}
```
</div>
(function traps) and
<div class="example">
``` example
trap '
# code
' NAL
```
</div>
(list traps) are equivalent in most ways, the exceptions being the
following:
- Function traps have all the properties of normal functions,
appearing in the list of functions and being called with their own
function context rather than the context where the trap was
triggered.
- The return status from function traps is special, whereas a return
from a list trap causes the surrounding context to return with the
given status.
- Function traps are not reset within subshells, in accordance with
zsh behaviour; list traps are reset, in accordance with POSIX
behaviour.
-----
This document was generated on *February 15, 2020* using
[*texi2html 5.0*](http://www.nongnu.org/texi2html/).
Zsh version 5.8, released on February 14, 2020.

173
src/Introduction.md Normal file
View File

@ -0,0 +1,173 @@
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [2 Introduction](#2-introduction)
- [2.1 Author](#21-author)
- [2.2 Availability](#22-availability)
- [2.3 Mailing Lists](#23-mailing-lists)
- [2.4 The Zsh FAQ](#24-the-zsh-faq)
- [2.5 The Zsh Web Page](#25-the-zsh-web-page)
- [2.6 The Zsh Userguide](#26-the-zsh-userguide)
- [2.7 See Also](#27-see-also)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<span id="Introduction"></span> <span id="Introduction-1"></span>
# 2 Introduction
<span id="index-introduction"></span>
Zsh is a UNIX command interpreter (shell) usable as an interactive login
shell and as a shell script command processor. Of the standard shells,
zsh most closely resembles ksh but includes many enhancements. It does
not provide compatibility with POSIX or other shells in its default
operating mode: see the section
[Compatibility](Invocation.html#Compatibility).
Zsh has command line editing, builtin spelling correction, programmable
command completion, shell functions (with autoloading), a history
mechanism, and a host of other features.
-----
<span id="Author"></span> <span id="Author-1"></span>
## 2.1 Author
<span id="index-author"></span>
Zsh was originally written by Paul Falstad `<pf@zsh.org>`. Zsh is now
maintained by the members of the zsh-workers mailing list
`<zsh-workers@zsh.org>`. The development is currently coordinated by
Peter Stephenson `<pws@zsh.org>`. The coordinator can be contacted at
`<coordinator@zsh.org>`, but matters relating to the code should
generally go to the mailing list.
-----
<span id="Availability"></span> <span id="Availability-1"></span>
## 2.2 Availability
Zsh is available from the following HTTP and anonymous FTP site.
<span id="index-FTP-sites-for-zsh"></span>
<span id="index-acquiring-zsh-by-FTP"></span>
<span id="index-availability-of-zsh"></span>
`ftp://ftp.zsh.org/pub/`
`https://www.zsh.org/pub/` )
The up-to-date source code is available via Git from Sourceforge. See
`https://sourceforge.net/projects/zsh/` for details. A summary of
instructions for the archive can be found at
`http://zsh.sourceforge.net/`.
-----
<span id="Mailing-Lists"></span> <span id="Mailing-Lists-1"></span>
## 2.3 Mailing Lists
<span id="index-mailing-lists"></span>
Zsh has 3 mailing lists:
- `<zsh-announce@zsh.org>`
Announcements about releases, major changes in the shell and the
monthly posting of the Zsh FAQ. (moderated)
- `<zsh-users@zsh.org>`
User discussions.
- `<zsh-workers@zsh.org>`
Hacking, development, bug reports and patches.
To subscribe or unsubscribe, send mail to the associated administrative
address for the mailing list.
`<zsh-announce-subscribe@zsh.org>`
`<zsh-users-subscribe@zsh.org>`
`<zsh-workers-subscribe@zsh.org>`
`<zsh-announce-unsubscribe@zsh.org>`
`<zsh-users-unsubscribe@zsh.org>`
`<zsh-workers-unsubscribe@zsh.org>`
YOU ONLY NEED TO JOIN ONE OF THE MAILING LISTS AS THEY ARE NESTED. All
submissions to zsh-announce are automatically forwarded to zsh-users.
All submissions to zsh-users are automatically forwarded to zsh-workers.
If you have problems subscribing/unsubscribing to any of the mailing
lists, send mail to `<listmaster@zsh.org>`. The mailing lists are
maintained by Karsten Thygesen `<karthy@kom.auc.dk>`.
The mailing lists are archived; the archives can be accessed via the
administrative addresses listed above. There is also a hypertext
archive, maintained by Geoff Wing `<gcw@zsh.org>`, available at
`https://www.zsh.org/mla/`.
-----
<span id="The-Zsh-FAQ"></span> <span id="The-Zsh-FAQ-1"></span>
## 2.4 The Zsh FAQ
Zsh has a list of Frequently Asked Questions (FAQ), maintained by Peter
Stephenson `<pws@zsh.org>`. It is regularly posted to the newsgroup
comp.unix.shell and the zsh-announce mailing list. The latest version
can be found at any of the Zsh FTP sites, or at
`http://www.zsh.org/FAQ/`. The contact address for FAQ-related matters
is `<faqmaster@zsh.org>`.
-----
<span id="The-Zsh-Web-Page"></span>
<span id="The-Zsh-Web-Page-1"></span>
## 2.5 The Zsh Web Page
Zsh has a web page which is located at `https://www.zsh.org/`. This is
maintained by Karsten Thygesen `<karthy@zsh.org>`, of SunSITE Denmark.
The contact address for web-related matters is `<webmaster@zsh.org>`.
-----
<span id="The-Zsh-Userguide"></span>
<span id="The-Zsh-Userguide-1"></span>
## 2.6 The Zsh Userguide
A userguide is currently in preparation. It is intended to complement
the manual, with explanations and hints on issues where the manual can
be cabbalistic, hierographic, or downright mystifying (for example, the
word hierographic does not exist). It can be viewed in its current
state at `http://zsh.sourceforge.net/Guide/`. At the time of writing,
chapters dealing with startup files and their contents and the new
completion system were essentially complete.
-----
<span id="See-Also"></span> <span id="See-Also-1"></span>
## 2.7 See Also
man page sh(1), man page csh(1), man page tcsh(1), man page rc(1), man
page bash(1), man page ksh(1)
IEEE Standard for information Technology - Part 2: Shell and Utilities,
IEEE Inc, 1993, ISBN 1-55937-255-9.
-----
This document was generated on *February 15, 2020* using
[*texi2html 5.0*](http://www.nongnu.org/texi2html/).
Zsh version 5.8, released on February 14, 2020.

266
src/Invocation.md Normal file
View File

@ -0,0 +1,266 @@
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [4 Invocation](#4-invocation)
- [4.1 Invocation](#41-invocation)
- [4.2 Compatibility](#42-compatibility)
- [4.3 Restricted Shell](#43-restricted-shell)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<span id="Invocation"></span> <span id="Invocation-1"></span>
# 4 Invocation
<span id="index-invocation"></span>
-----
<span id="Invocation-2"></span>
## 4.1 Invocation
<span id="index-shell-options"></span>
<span id="index-options_002c-shell"></span>
<span id="index-shell-flags"></span>
<span id="index-flags_002c-shell"></span>
The following flags are interpreted by the shell when invoked to
determine where the shell will read commands from:
- `-c`
Take the first argument as a command to execute, rather than reading
commands from a script or standard input. If any further arguments
are given, the first one is assigned to `$0`, rather than being used
as a positional parameter.
- `-i`
Force shell to be interactive. It is still possible to specify a
script to execute.
- `-s`
Force shell to read commands from the standard input. If the `-s`
flag is not present and an argument is given, the first argument is
taken to be the pathname of a script to execute.
If there are any remaining arguments after option processing, and
neither of the options `-c` or `-s` was supplied, the first argument is
taken as the file name of a script containing shell commands to be
executed. If the option `PATH_SCRIPT` is set, and the file name does not
contain a directory path (i.e. there is no `/` in the name), first the
current directory and then the command path given by the variable `PATH`
are searched for the script. If the option is not set or the file name
contains a `/` it is used directly.
After the first one or two arguments have been appropriated as described
above, the remaining arguments are assigned to the positional
parameters.
For further options, which are common to invocation and the `set`
builtin, see [Options](Options.html#Options).
The long option `-``-emulate` followed (in a separate word) by an
emulation mode may be passed to the shell. The emulation modes are those
described for the `emulate` builtin, see [Shell Builtin
Commands](Shell-Builtin-Commands.html#Shell-Builtin-Commands). The
`-``-emulate` option must precede any other options (which might
otherwise be overridden), but following options are honoured, so may be
used to modify the requested emulation mode. Note that certain extra
steps are taken to ensure a smooth emulation when this option is used
compared with the `emulate` command within the shell: for example,
variables that conflict with POSIX usage such as `path` are not defined
within the shell.
Options may be specified by name using the `-o` option. `-o` acts like a
single-letter option, but takes a following string as the option name.
For example,
<div class="example">
``` example
zsh -x -o shwordsplit scr
```
</div>
runs the script `scr`, setting the `XTRACE` option by the corresponding
letter `-x` and the `SH_WORD_SPLIT` option by name. Options may be
turned *off* by name by using `+o` instead of `-o`. `-o` can be stacked
up with preceding single-letter options, so for example `-xo
shwordsplit` or `-xoshwordsplit` is equivalent to `-x -o
shwordsplit`.
<span id="index-long-option"></span>
Options may also be specified by name in GNU long option style,
`-``-``option-name`. When this is done, `-` characters in the
option name are permitted: they are translated into `_`, and thus
ignored. So, for example, `zsh -``-sh-word-split` invokes zsh with the
`SH_WORD_SPLIT` option turned on. Like other option syntaxes, options
can be turned off by replacing the initial `-` with a `+`; thus
`+-sh-word-split` is equivalent to `-``-no-sh-word-split`. Unlike
other option syntaxes, GNU-style long options cannot be stacked with any
other options, so for example `-x-shwordsplit` is an error, rather
than being treated like `-x -``-shwordsplit`.
<span id="index-_002d_002dversion"></span>
<span id="index-_002d_002dhelp"></span>
The special GNU-style option `-``-version` is handled; it sends to
standard output the shells version information, then exits
successfully. `-``-help` is also handled; it sends to standard output
a list of options that can be used when invoking the shell, then exits
successfully.
Option processing may be finished, allowing following arguments that
start with `-` or `+` to be treated as normal arguments, in two
ways. Firstly, a lone `-` (or `+`) as an argument by itself ends
option processing. Secondly, a special option `-``-` (or `+-`),
which may be specified on its own (which is the standard POSIX usage) or
may be stacked with preceding options (so `-x-` is equivalent to `-x
-``-`). Options are not permitted to be stacked after `-``-` (so
`-x-f` is an error), but note the GNU-style option form discussed
above, where `-``-shwordsplit` is permitted and does not end option
processing.
Except when the sh/ksh emulation single-letter options are in effect,
the option `-b` (or `+b`) ends option processing. `-b` is like
`-``-`, except that further single-letter options can be stacked
after the `-b` and will take effect as normal.
-----
<span id="Compatibility"></span> <span id="Compatibility-1"></span>
## 4.2 Compatibility
<span id="index-compatibility"></span>
<span id="index-sh-compatibility"></span>
<span id="index-ksh-compatibility"></span>
Zsh tries to emulate sh or ksh when it is invoked as `sh` or `ksh`
respectively; more precisely, it looks at the first letter of the name
by which it was invoked, excluding any initial `r` (assumed to stand
for restricted), and if that is `b`, `s` or `k` it will emulate
sh or ksh. Furthermore, if invoked as `su` (which happens on certain
systems when the shell is executed by the `su` command), the shell will
try to find an alternative name from the `SHELL` environment variable
and perform emulation based on that.
In sh and ksh compatibility modes the following parameters are not
special and not initialized by the shell: `ARGC`, `argv`, `cdpath`,
`fignore`, `fpath`, `HISTCHARS`, `mailpath`, `MANPATH`, `manpath`,
`path`, `prompt`, `PROMPT`, `PROMPT2`, `PROMPT3`, `PROMPT4`, `psvar`,
`status`, `watch`.
<span id="index-ENV_002c-use-of"></span>
The usual zsh startup/shutdown scripts are not executed. Login shells
source `/etc/profile` followed by `$HOME/.profile`. If the `ENV`
environment variable is set on invocation, `$ENV` is sourced after the
profile scripts. The value of `ENV` is subjected to parameter expansion,
command substitution, and arithmetic expansion before being interpreted
as a pathname. Note that the `PRIVILEGED` option also affects the
execution of startup files.
The following options are set if the shell is invoked as `sh` or `ksh`:
`NO_BAD_PATTERN`, `NO_BANG_HIST`, `NO_BG_NICE`, `NO_EQUALS`,
`NO_FUNCTION_ARGZERO`, `GLOB_SUBST`, `NO_GLOBAL_EXPORT`, `NO_HUP`,
`INTERACTIVE_COMMENTS`, `KSH_ARRAYS`, `NO_MULTIOS`, `NO_NOMATCH`,
`NO_NOTIFY`, `POSIX_BUILTINS`, `NO_PROMPT_PERCENT`, `RM_STAR_SILENT`,
`SH_FILE_EXPANSION`, `SH_GLOB`, `SH_OPTION_LETTERS`, `SH_WORD_SPLIT`.
Additionally the `BSD_ECHO` and `IGNORE_BRACES` options are set if zsh
is invoked as `sh`. Also, the `KSH_OPTION_PRINT`, `LOCAL_OPTIONS`,
`PROMPT_BANG`, `PROMPT_SUBST` and `SINGLE_LINE_ZLE` options are set if
zsh is invoked as `ksh`.
-----
<span id="Restricted-Shell"></span>
<span id="Restricted-Shell-1"></span>
## 4.3 Restricted Shell
<span id="index-restricted-shell"></span>
<span id="index-RESTRICTED"></span>
When the basename of the command used to invoke zsh starts with the
letter `r` or the `-r` command line option is supplied at
invocation, the shell becomes restricted. Emulation mode is determined
after stripping the letter `r` from the invocation name. The following
are disabled in restricted mode:
- changing directories with the `cd` builtin
- changing or unsetting the `EGID`, `EUID`, `GID`, `HISTFILE`,
`HISTSIZE`, `IFS`, `LD_AOUT_LIBRARY_PATH`, `LD_AOUT_PRELOAD`,
`LD_LIBRARY_PATH`, `LD_PRELOAD`, `MODULE_PATH`, `module_path`,
`PATH`, `path`, `SHELL`, `UID` and `USERNAME` parameters
- specifying command names containing `/`
- specifying command pathnames using `hash`
- redirecting output to files
- using the `exec` builtin command to replace the shell with another
command
- using `jobs -Z` to overwrite the shell process argument and
environment space
- using the `ARGV0` parameter to override `argv[0]` for external
commands
- turning off restricted mode with `set +r` or `unsetopt RESTRICTED`
These restrictions are enforced after processing the startup files. The
startup files should set up `PATH` to point to a directory of commands
which can be safely invoked in the restricted environment. They may also
add further restrictions by disabling selected builtins.
Restricted mode can also be activated any time by setting the
`RESTRICTED` option. This immediately enables all the restrictions
described above even if the shell still has not processed all startup
files.
A shell *Restricted Mode* is an outdated way to restrict what users may
do: modern systems have better, safer and more reliable ways to confine
user actions, such as *chroot jails*, *containers* and *zones*.
A restricted shell is very difficult to implement safely. The feature
may be removed in a future version of zsh.
It is important to realise that the restrictions only apply to the
shell, not to the commands it runs (except for some shell builtins).
While a restricted shell can only run the restricted list of commands
accessible via the predefined `PATH` variable, it does not prevent
those commands from running any other command.
As an example, if `env` is among the list of *allowed* commands, then
it allows the user to run any command as `env` is not a shell
So when implementing a restricted shell framework it is important to be
fully aware of what actions each of the *allowed* commands or features
(which may be regarded as *modules*) can perform.
Many commands can have their behaviour affected by environment
variables. Except for the few listed above, zsh does not restrict the
setting of environment variables.
If a `perl`, `python`, `bash`, or other general purpose
interpreted script it treated as a restricted command, the user can work
around the restriction by setting specially crafted `PERL5LIB`,
`PYTHONPATH`, `BASHENV` (etc.) environment variables. On GNU
systems, any command can be made to run arbitrary code when performing
character set conversion (including zsh itself) by setting a
`GCONV_PATH` environment variable. Those are only a few examples.
Bear in mind that, contrary to some other shells, `readonly` is not a
security feature in zsh as it can be undone and so cannot be used to
mitigate the above.
A restricted shell only works if the allowed commands are few and
carefully written so as not to grant more access to users than intended.
It is also important to restrict what zsh module the user may load as
some of them, such as `zsh/system`, `zsh/mapfile` and `zsh/files`,
allow bypassing most of the restrictions.
-----
This document was generated on *February 15, 2020* using
[*texi2html 5.0*](http://www.nongnu.org/texi2html/).
Zsh version 5.8, released on February 14, 2020.

170
src/Jobs-_0026-Signals.md Normal file
View File

@ -0,0 +1,170 @@
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [10 Jobs & Signals](#10-jobs--signals)
- [10.1 Jobs](#101-jobs)
- [10.2 Signals](#102-signals)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<span id="Jobs-_0026-Signals"></span>
<span id="Jobs-_0026-Signals-1"></span>
# 10 Jobs & Signals
-----
<span id="Jobs"></span>
## 10.1 Jobs
<span id="index-jobs"></span>
<span id="index-MONITOR_002c-use-of"></span>
If the `MONITOR` option is set, an interactive shell associates a *job*
with each pipeline. command, and assigns them small integer numbers.
When a job is started asynchronously with `&`, the shell prints a line
to standard error which looks like:
<div class="example">
``` example
[1] 1234
```
</div>
indicating that the job which was started asynchronously was job number
1 and had one (top-level) process, whose process ID was 1234.
If a job is started with `&|` or `&!`, then that job is immediately
disowned. After startup, it to the job control features described here.
If you are running a job and wish to do something else you may hit the
key ^Z (control-Z) which sends a `TSTP` signal to the current job: this
key may be redefined by the `susp` option of the external `stty`
command. <span id="index-jobs_002c-suspending"></span>
<span id="index-suspending-jobs"></span> The shell will then normally
indicate that the job has been suspended, and print another prompt.
You can then manipulate the state of this job,
<span id="index-bg_002c-use-of"></span> putting it in the background
with the `bg` command, or run some other commands and then eventually
bring the job back into the foreground with
<span id="index-fg_002c-use-of"></span> the foreground command `fg`. A
^Z takes effect immediately and is like an interrupt in that pending
output and unread input are discarded when it is typed.
A job being run in the background will suspend if it tries to read from
the terminal.
Note that if the job running in the foreground is a shell function, then
suspending it will have the effect of causing the shell to fork. This is
necessary to separate the functions state from that of the parent shell
performing the job control, so that the latter can return to the command
line prompt. As a result, even if `fg` is used to continue the job the
function will no longer be part of the parent shell, and any variables
set by the function will not be visible in the parent shell. Thus the
behaviour is different from the case where the function was never
suspended. Zsh is different from many other shells in this regard.
One additional side effect is that use of `disown` with a job created by
suspending shell code in this fashion is delayed: the job can only be
disowned once any process started from the parent shell has terminated.
At that point, the disowned job disappears silently from the job list.
The same behaviour is found when the shell is executing code as the
right hand side of a pipeline or any complex shell construct such as
`if`, `for`, etc., in order that the entire block of code can be managed
as a single job. <span id="index-background-jobs_002c-I_002fO"></span>
<span id="index-jobs_002c-background_002c-I_002fO"></span> Background
jobs are normally allowed to produce output, but this can be disabled by
giving the command `stty tostop`. If you set this tty option, then
background jobs will suspend when they try to produce output like they
do when they try to read input.
When a command is suspended and continued later with the `fg` or `wait`
builtins, zsh restores tty modes that were in effect when it was
suspended. This (intentionally) does not apply if the command is
continued via `kill -CONT`, nor when it is continued with `bg`.
<span id="index-jobs_002c-referring-to"></span>
<span id="index-referring-to-jobs"></span>
There are several ways to refer to jobs in the shell. A job can be
referred to by the process ID of any process of the job or by one of the
following:
- `%``number`
The job with the given number.
- `%``string`
The last job whose command line begins with `string`.
- `%?``string`
The last job whose command line contains `string`.
- `%%`
Current job.
- `%+`
Equivalent to `%%`.
- `%-`
Previous job.
The shell learns immediately whenever a process changes state.
<span id="index-NOTIFY_002c-use-of"></span> It normally informs you
whenever a job becomes blocked so that no further progress is possible.
If the `NOTIFY` option is not set, it waits until just before it prints
a prompt before it informs you. All such notifications are sent directly
to the terminal, not to the standard output or standard error.
When the monitor mode is on, each background job that completes triggers
any trap set for `CHLD`.
When you try to leave the shell while jobs are running or suspended, you
will be warned that You have suspended (running) jobs. You may use the
`jobs` command to see what they are. If you do this or immediately try
to exit again, the shell will not warn you a second time; the suspended
jobs will be terminated, and the running jobs will be sent a `SIGHUP`
signal, if the `HUP` option is set.
<span id="index-HUP_002c-use-of"></span>
<span id="index-jobs_002c-disowning"></span>
<span id="index-disowning-jobs"></span>
<span id="index-disown_002c-use-of"></span>
To avoid having the shell terminate the running jobs, either use the
nohup command (see man page nohup(1)) or the `disown` builtin.
-----
<span id="Signals"></span>
## 10.2 Signals
The `INT` and `QUIT` signals for an invoked command are ignored if the
command is followed by `&` and the `MONITOR` option is not active. The
shell itself always ignores the `QUIT` signal. Otherwise, signals have
the values inherited by the shell from its parent (but see the
`TRAP``NAL` special functions in [Functions](Functions.html#Functions)).
<span id="index-exiting-shell_002c-and-asynchronous-jobs"></span>
<span id="index-asynchronous-jobs_002c-and-exiting-shell"></span>
<span id="index-jobs_002c-asynchronous_002c-and-exiting-shell"></span>
Certain jobs are run asynchronously by the shell other than those
explicitly put into the background; even in cases where the shell would
usually wait for such jobs, an explicit `exit` command or exit due to
the option `ERR_EXIT` will cause the shell to exit without waiting.
Examples of such asynchronous jobs are process substitution, see
[Process Substitution](Expansion.html#Process-Substitution), and the
handler processes for multios, see the section Multios in
[Redirection](Redirection.html#Redirection).
-----
This document was generated on *February 15, 2020* using
[*texi2html 5.0*](http://www.nongnu.org/texi2html/).
Zsh version 5.8, released on February 14, 2020.

75
src/Options-Index.md Normal file
View File

@ -0,0 +1,75 @@
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [Options Index](#options-index)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<span id="Options-Index"></span> <span id="Options-Index-1"></span>
# Options Index
  [**B**](#Options-Index-1_pg_letter-B)  
[**C**](#Options-Index-1_pg_letter-C)  
[**D**](zsh_9.html#index_split-8_pg_letter-D)  
[**E**](zsh_9.html#index_split-8_pg_letter-E)  
[**F**](zsh_9.html#index_split-8_pg_letter-F)  
[**G**](zsh_9.html#index_split-8_pg_letter-G)  
[**H**](zsh_9.html#index_split-8_pg_letter-H)  
[**I**](zsh_9.html#index_split-8_pg_letter-I)  
[**K**](zsh_10.html#index_split-9_pg_letter-K)  
[**L**](zsh_10.html#index_split-9_pg_letter-L)  
[**M**](zsh_10.html#index_split-9_pg_letter-M)  
[**N**](zsh_10.html#index_split-9_pg_letter-N)  
[**O**](zsh_11.html#index_split-10_pg_letter-O)  
[**P**](zsh_11.html#index_split-10_pg_letter-P)  
[**R**](zsh_11.html#index_split-10_pg_letter-R)  
[**S**](zsh_11.html#index_split-10_pg_letter-S)  
[**T**](zsh_12.html#index_split-11_pg_letter-T)  
[**U**](zsh_12.html#index_split-11_pg_letter-U)  
[**V**](zsh_12.html#index_split-11_pg_letter-V)  
[**W**](zsh_12.html#index_split-11_pg_letter-W)  
[**X**](zsh_12.html#index_split-11_pg_letter-X)  
[**Z**](zsh_12.html#index_split-11_pg_letter-Z)  
Index Entry
 
Section
<span id="Options-Index-1_pg_letter-A">A</span>
<span id="Options-Index-1_pg_letter-B">B</span>
<span id="Options-Index-1_pg_letter-C">C</span>
  [**B**](#Options-Index-1_pg_letter-B)  
[**C**](#Options-Index-1_pg_letter-C)  
[**D**](zsh_9.html#index_split-8_pg_letter-D)  
[**E**](zsh_9.html#index_split-8_pg_letter-E)  
[**F**](zsh_9.html#index_split-8_pg_letter-F)  
[**G**](zsh_9.html#index_split-8_pg_letter-G)  
[**H**](zsh_9.html#index_split-8_pg_letter-H)  
[**I**](zsh_9.html#index_split-8_pg_letter-I)  
[**K**](zsh_10.html#index_split-9_pg_letter-K)  
[**L**](zsh_10.html#index_split-9_pg_letter-L)  
[**M**](zsh_10.html#index_split-9_pg_letter-M)  
[**N**](zsh_10.html#index_split-9_pg_letter-N)  
[**O**](zsh_11.html#index_split-10_pg_letter-O)  
[**P**](zsh_11.html#index_split-10_pg_letter-P)  
[**R**](zsh_11.html#index_split-10_pg_letter-R)  
[**S**](zsh_11.html#index_split-10_pg_letter-S)  
[**T**](zsh_12.html#index_split-11_pg_letter-T)  
[**U**](zsh_12.html#index_split-11_pg_letter-U)  
[**V**](zsh_12.html#index_split-11_pg_letter-V)  
[**W**](zsh_12.html#index_split-11_pg_letter-W)  
[**X**](zsh_12.html#index_split-11_pg_letter-X)  
[**Z**](zsh_12.html#index_split-11_pg_letter-Z)  
-----
This document was generated on *February 15, 2020* using
[*texi2html 5.0*](http://www.nongnu.org/texi2html/).
Zsh version 5.8, released on February 14, 2020.

3250
src/Options.md Normal file

File diff suppressed because it is too large Load Diff

2242
src/Parameters.md Normal file

File diff suppressed because it is too large Load Diff

469
src/Prompt-Expansion.md Normal file
View File

@ -0,0 +1,469 @@
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [13 Prompt Expansion](#13-prompt-expansion)
- [13.1 Expansion of Prompt Sequences](#131-expansion-of-prompt-sequences)
- [13.2 Simple Prompt Escapes](#132-simple-prompt-escapes)
- [13.2.1 Special characters](#1321-special-characters)
- [13.2.2 Login information](#1322-login-information)
- [13.2.3 Shell state](#1323-shell-state)
- [13.2.4 Date and time](#1324-date-and-time)
- [13.2.5 Visual effects](#1325-visual-effects)
- [13.3 Conditional Substrings in Prompts](#133-conditional-substrings-in-prompts)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<span id="Prompt-Expansion"></span>
<span id="Prompt-Expansion-1"></span>
# 13 Prompt Expansion
-----
<span id="Expansion-of-Prompt-Sequences"></span>
## 13.1 Expansion of Prompt Sequences
<span id="index-prompt-expansion"></span>
<span id="index-expansion_002c-prompt"></span>
Prompt sequences undergo a special form of expansion. This type of
expansion is also available using the `-P` option to the `print`
builtin.
<span id="index-PROMPT_005fSUBST_002c-use-of"></span>
If the `PROMPT_SUBST` option is set, the prompt string is first
subjected to *parameter expansion*, *command substitution* and
*arithmetic expansion*. See [Expansion](Expansion.html#Expansion).
Certain escape sequences may be recognised in the prompt string.
<span id="index-PROMPT_005fBANG_002c-use-of"></span>
If the `PROMPT_BANG` option is set, a `!` in the prompt is replaced by
the current history event number. A literal `!` may then be
represented as `!!`.
<span id="index-PROMPT_005fPERCENT_002c-use-of"></span>
If the `PROMPT_PERCENT` option is set, certain escape sequences that
start with `%` are expanded. Many escapes are followed by a single
character, although some of these take an optional integer argument that
should appear between the `%` and the next character of the sequence.
More complicated escape sequences are available to provide conditional
expansion.
-----
<span id="Simple-Prompt-Escapes"></span>
## 13.2 Simple Prompt Escapes
-----
<span id="Special-characters"></span>
### 13.2.1 Special characters
- `%%`
A `%`.
- `%)`
A `)`.
-----
<span id="Login-information"></span>
### 13.2.2 Login information
- `%l`
The line (tty) the user is logged in on, without `/dev/` prefix.
If the name starts with `/dev/tty`, that prefix is stripped.
- `%M`
The full machine hostname.
- `%m`
The hostname up to the first `.`. An integer may follow the `%`
to specify how many components of the hostname are desired. With a
negative integer, trailing components of the hostname are shown.
- `%n`
`$USERNAME`.
- `%y`
The line (tty) the user is logged in on, without `/dev/` prefix.
This does not treat `/dev/tty` names specially.
-----
<span id="Shell-state"></span>
### 13.2.3 Shell state
- `%#`
A `#` if the shell is running with privileges, a `%` if not.
Equivalent to `%(!.#.%%)`. The definition of privileged, for
these purposes, is that either the effective user ID is zero, or, if
POSIX.1e capabilities are supported, that capability vectors.
- `%?`
The return status of the last command executed just before the
prompt.
- `%_`
The status of the parser, i.e. the shell constructs (like `if` and
`for`) that have been started on the command line. If given an
integer number that many strings will be printed; zero or negative
or no integer means print as many as there are. This is most useful
in prompts `PS2` for continuation lines and `PS4` for debugging with
the `XTRACE` option; in the latter case it will also work
non-interactively.
- `%^`
The status of the parser in reverse. This is the same as `%_`
other than the order of strings. It is often used in `RPS2`.
- `%d`
`%/`
Current working directory. If an integer follows the `%`, it
specifies a number of trailing components of the current working
directory to show; zero means the whole path. A negative integer
specifies leading components, i.e. `%-1d` specifies the first
component.
- `%~`
As `%d` and `%/`, but if the current working directory starts with
`$HOME`, that part is replaced by a `~`. Furthermore, if it has a
named directory as its prefix, that part is replaced by a `~`
followed by the name of the directory, but only if the result is
shorter than the full path; [Filename
Expansion](Expansion.html#Filename-Expansion).
- `%e`
Evaluation depth of the current sourced file, shell function, or
`eval`. This is incremented or decremented every time the value of
`%N` is set or reverted to a previous value, respectively. This is
most useful for debugging as part of `$PS4`.
- `%h`
`%!`
Current history event number.
- `%i`
The line number currently being executed in the script, sourced
file, or shell function given by `%N`. This is most useful for
debugging as part of `$PS4`.
- `%I`
The line number currently being executed in the file `%x`. This is
similar to `%i`, but the line number is always a line number in the
file where the code was defined, even if the code is a shell
function.
- `%j`
The number of jobs.
- `%L`
The current value of `$SHLVL`.
- `%N`
The name of the script, sourced file, or shell function that zsh is
currently executing, whichever was started most recently. If there
is none, this is equivalent to the parameter `$0`. An integer may
follow the `%` to specify a number of trailing path components to
show; zero means the full path. A negative integer specifies leading
components.
- `%x`
The name of the file containing the source code currently being
executed. This behaves as `%N` except that function and eval command
names are not shown, instead the file where they were defined.
- `%c`
`%.`
`%C`
Trailing component of the current working directory. An integer may
follow the `%` to get more than one component. Unless `%C` is
used, tilde contraction is performed first. These are deprecated as
`%c` and `%C` are equivalent to `%1~` and `%1/`, respectively, while
explicit positive integers have the same effect as for the latter
two sequences.
-----
<span id="Date-and-time"></span>
### 13.2.4 Date and time
- `%D`
The date in `yy``-``mm``-``dd` format.
- `%T`
Current time of day, in 24-hour format.
- `%t`
`%@`
Current time of day, in 12-hour, am/pm format.
- `%*`
Current time of day in 24-hour format, with seconds.
- `%w`
The date in `day``-``dd` format.
- `%W`
The date in `mm``/``dd``/``yy` format.
- `%D{``string``}`
`string` is formatted using the `strftime` function. See man page
strftime(3) for more details. Various zsh extensions provide numbers
with no leading zero or space if the number is a single digit:
- `%f`
a day of the month
- `%K`
the hour of the day on the 24-hour clock
- `%L`
the hour of the day on the 12-hour clock
In addition, if the system supports the POSIX `gettimeofday` system
call, `%.` provides decimal fractions of a second since the epoch
with leading zeroes. By default three decimal places are provided,
but a number of digits up to 9 may be given following the `%`; hence
`%6.` outputs microseconds, and `%9.` outputs nanoseconds. (The
latter requires a nanosecond-precision `clock_gettime`; systems
lacking this will return a value multiplied by the appropriate power
of 10.) A typical example of this is the format `%D{%H:%M:%S.%.}`.
The GNU extension `%N` is handled as a synonym for `%9.`.
Additionally, the GNU extension that a `-` between the `%` and the
format character causes a leading zero or space to be stripped is
handled directly by the shell for the format characters `d`, `f`,
`H`, `k`, `l`, `m`, `M`, `S` and `y`; any other format characters
are provided to the systems strftime(3) with any leading `-`
present, so the handling is system dependent. Further GNU (or other)
extensions are also passed to strftime(3) and may work if the system
supports them.
-----
<span id="Visual-effects"></span>
### 13.2.5 Visual effects
- `%B` (`%b`)
Start (stop) boldface mode.
- `%E`
Clear to end of line.
- `%U` (`%u`)
Start (stop) underline mode.
- `%S` (`%s`)
Start (stop) standout mode.
- `%F` (`%f`)
Start (stop) using a different foreground colour, if supported by
the terminal. The colour may be specified two ways: either as a
numeric argument, as normal, or by a sequence in braces following
the `%F`, for example `%F{red}`. In the latter case the values
allowed are as described for the `fg` `zle_highlight` attribute;
[Character
Highlighting](Zsh-Line-Editor.html#Character-Highlighting). This
means that numeric colours are allowed in the second format also.
- `%K` (`%k`)
Start (stop) using a different bacKground colour. The syntax is
identical to that for `%F` and `%f`.
- `%{`...`%}`
Include a string as a literal escape sequence. The string within the
braces should not change the cursor position. Brace pairs can nest.
A positive numeric argument between the `%` and the `{` is treated
as described for `%G` below.
- `%G`
Within a `%{`...`%}` sequence, include a glitch: that is, assume
that a single character width will be output. This is useful when
outputting characters that otherwise cannot be correctly handled by
the shell, such as the alternate character set on some terminals.
The characters in question can be included within a `%{`...`%}`
sequence together with the appropriate number of `%G` sequences to
indicate the correct width. An integer between the `%` and `G`
indicates a character width other than one. Hence `%{``seq``%2G%}`
outputs `seq` and assumes it takes up the width of two standard
characters.
Multiple uses of `%G` accumulate in the obvious fashion; the
position of the `%G` is unimportant. Negative integers are not
handled.
Note that when prompt truncation is in use it is advisable to divide
up output into single characters within each `%{`...`%}` group so
that the correct truncation point can be found.
-----
<span id="Conditional-Substrings-in-Prompts"></span>
## 13.3 Conditional Substrings in Prompts
- `%v`
<span id="index-psvar_002c-use-of"></span>
The value of the first element of the `psvar` array parameter.
Following the `%` with an integer gives that element of the array.
Negative integers count from the end of the array.
- `%(``x``.``true-text``.``false-text``)`
Specifies a ternary expression. The character following the `x` is
arbitrary; the same character is used to separate the text for the
true result from that for the false result. This separator may
not appear in the `true-text`, except as part of a %-escape
sequence. A `)` may appear in the `false-text` as `%)`.
`true-text` and `false-text` may both contain arbitrarily-nested
escape sequences, including further ternary expressions.
The left parenthesis may be preceded or followed by a positive
integer `n`, which defaults to zero. A negative integer will be
multiplied by -1, except as noted below for `l`. The test
character `x` may be any of the following:
- `!`
True if the shell is running with privileges.
- `#`
True if the effective uid of the current process is `n`.
- `?`
True if the exit status of the last command was `n`.
- `_`
True if at least `n` shell constructs were started.
- `C`
`/`
True if the current absolute path has at least `n` elements
relative to the root directory, hence `/` is counted as 0
elements.
- `c`
`.`
`~`
True if the current path, with prefix replacement, has at least
`n` elements relative to the root directory, hence `/` is
counted as 0 elements.
- `D`
True if the month is equal to `n` (January = 0).
- `d`
True if the day of the month is equal to `n`.
- `e`
True if the evaluation depth is at least `n`.
- `g`
True if the effective gid of the current process is `n`.
- `j`
True if the number of jobs is at least `n`.
- `L`
True if the `SHLVL` parameter is at least `n`.
- `l`
True if at least `n` characters have already been printed on the
current line. When `n` is negative, true if at least
`abs``(``n``)` characters remain before the opposite margin
(thus the left margin for `RPROMPT`).
- `S`
True if the `SECONDS` parameter is at least `n`.
- `T`
True if the time in hours is equal to `n`.
- `t`
True if the time in minutes is equal to `n`.
- `v`
True if the array `psvar` has at least `n` elements.
- `V`
True if element `n` of the array `psvar` is set and non-empty.
- `w`
True if the day of the week is equal to `n` (Sunday = 0).
- `%<``string``<`
`%>``string``>`
`%[``xstring``]`
Specifies truncation behaviour for the remainder of the prompt
string. The third, deprecated, form is equivalent to
`%``xstringx`, i.e. `x` may be `<` or `>`. The `string`
will be displayed in place of the truncated portion of any string;
note this does not undergo prompt expansion.
The numeric argument, which in the third form may appear immediately
after the `[`, specifies the maximum permitted length of the
various strings that can be displayed in the prompt. In the first
two forms, this numeric argument may be negative, in which case the
truncation length is determined by subtracting the absolute value of
the numeric argument from the number of character positions
remaining on the current prompt line. If this results in a zero or
negative length, a length of 1 is used. In other words, a negative
argument arranges that after truncation at least `n` characters
remain before the right margin (left margin for `RPROMPT`).
The forms with `<` truncate at the left of the string, and the
forms with `>` truncate at the right of the string. For example,
if the current directory is `/home/pike`, the prompt `%8<..<%/`
will expand to `..e/pike`. In this string, the terminating
character (`<`, `>` or `]`), or in fact any character, may be
quoted by a preceding `\`; note when using `print -P`, however,
that this must be doubled as the string is also subject to standard
`print` processing, in addition to any backslashes removed by a
double quoted string: the worst case is therefore `print -P
"%<\\\\<<..."`.
If the `string` is longer than the specified truncation length, it
will appear in full, completely replacing the truncated string.
The part of the prompt string to be truncated runs to the end of the
string, or to the end of the next enclosing group of the `%(`
construct, or to the next truncation encountered at the same
grouping level (i.e. truncations inside a `%(` are separate),
which ever comes first. In particular, a truncation with argument
zero (e.g., `%<<`) marks the end of the range of the string to be
truncated while turning off truncation from there on. For example,
the prompt ` %10<...<%~%<<%# ` will print a truncated
representation of the current directory, followed by a `%` or
`#`, followed by a space. Without the `%<<`, those two
characters would be included in the string to be truncated. Note
that `%-0<<` is not equivalent to `%<<` but specifies that the
prompt is truncated at the right margin.
Truncation applies only within each individual line of the prompt,
as delimited by embedded newlines (if any). If the total length of
any line of the prompt after truncation is greater than the terminal
width, or if the part to be truncated contains embedded newlines,
truncation behavior is undefined and may change in a future version
of the shell. Use `%-``n``(l.``true-text``.``false-text``)` to
remove parts of the prompt when the available space is less than
`n`.
-----
This document was generated on *February 15, 2020* using
[*texi2html 5.0*](http://www.nongnu.org/texi2html/).
Zsh version 5.8, released on February 14, 2020.

460
src/Redirection.md Normal file
View File

@ -0,0 +1,460 @@
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [7 Redirection](#7-redirection)
- [7.1 Opening file descriptors using parameters](#71-opening-file-descriptors-using-parameters)
- [7.2 Multios](#72-multios)
- [7.3 Redirections with no command](#73-redirections-with-no-command)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<span id="Redirection"></span> <span id="Redirection-1"></span>
# 7 Redirection
<span id="index-redirection"></span>
<span id="index-file-descriptors"></span>
<span id="index-descriptors_002c-file"></span>
If a command is followed by `&` and job control is not active, then the
default standard input for the command is the empty file `/dev/null`.
Otherwise, the environment for the execution of a command contains the
file descriptors of the invoking shell as modified by input/output
specifications.
The following may appear anywhere in a simple command or may precede or
follow a complex command. Expansion occurs before `word` or `digit` is
used except as noted below. If the result of substitution on `word`
produces more than one filename, redirection occurs for each separate
filename in turn.
- `<` `word`
Open file `word` for reading as standard input. It is an error to
open a file in this fashion if it does not exist.
- `<>` `word`
Open file `word` for reading and writing as standard input. If the
file does not exist then it is created.
- `>` `word`
Open file `word` for writing as standard output. If the file does
not exist then it is created. If the file exists, and the `CLOBBER`
option is unset, this causes an error; otherwise, it is truncated to
zero length.
- `>|` `word`
`>!` `word`
Same as `>`, except that the file is truncated to zero length if it
exists, regardless of `CLOBBER`.
- `>>` `word`
Open file `word` for writing in append mode as standard output. If
the file does not exist, and the `CLOBBER` and `APPEND_CREATE`
options are both unset, this causes an error; otherwise, the file is
created.
- `>>|` `word`
`>>!` `word`
Same as `>>`, except that the file is created if it does not exist,
regardless of `CLOBBER` and `APPEND_CREATE`.
- `<<`\[`-`\] `word`
The shell input is read up to a line that is the same as `word`, or
to an end-of-file. No parameter expansion, command substitution or
filename generation is performed on `word`. The resulting document,
called a *here-document*, becomes the standard input.
If any character of `word` is quoted with single or double quotes or
a `\`, no interpretation is placed upon the characters of the
document. Otherwise, parameter and command substitution occurs,
`\` followed by a newline is removed, and `\` must be used
to quote the characters `\`, `$`, `` and the first character
of `word`.
Note that `word` itself does not undergo shell expansion. Backquotes
in `word` do not have their usual effect; instead they behave
similarly to double quotes, except that the backquotes themselves
are passed through unchanged. (This information is given for
completeness and it is not recommended that backquotes be used.)
Quotes in the form `$``...``` have their standard effect of
expanding backslashed references to special characters.
If `<<-` is used, then all leading tabs are stripped from `word` and
from the document.
- `<<<` `word`
Perform shell expansion on `word` and pass the result to standard
input. This is known as a *here-string*. Compare the use of `word`
in here-documents above, where `word` does not undergo shell
expansion.
- `<&` `number`
`>&` `number`
The standard input/output is duplicated from file descriptor
`number` (see man page dup2(2)).
- `<& -`
`>& -`
Close the standard input/output.
- `<& p`
`>& p`
The input/output from/to the coprocess is moved to the standard
input/output.
- `>&` `word`
`&>` `word`
(Except where `>&` `word` matches one of the above syntaxes;
`&>` can always be used to avoid this ambiguity.) Redirects
both standard output and standard error (file descriptor 2) in the
manner of `>` `word`. Note that this does *not* have the same
effect as `>` `word` `2>&1` in the presence of multios (see the
section below).
- `>&|` `word`
`>&!` `word`
`&>|` `word`
`&>!` `word`
Redirects both standard output and standard error (file descriptor
2) in the manner of `>|` `word`.
- `>>&` `word`
`&>>` `word`
Redirects both standard output and standard error (file descriptor
2) in the manner of `>>` `word`.
- `>>&|` `word`
`>>&!` `word`
`&>>|` `word`
`&>>!` `word`
Redirects both standard output and standard error (file descriptor
2) in the manner of `>>|` `word`.
If one of the above is preceded by a digit, then the file descriptor
referred to is that specified by the digit instead of the default 0 or
1. The order in which redirections are specified is significant. The
shell evaluates each redirection in terms of the (*file descriptor*,
*file*) association at the time of evaluation. For example:
> ... `1>``fname` `2>&1`
first associates file descriptor 1 with file `fname`. It then associates
file descriptor 2 with the file associated with file descriptor 1 (that
is, `fname`). If the order of redirections were reversed, file
descriptor 2 would be associated with the terminal (assuming file
descriptor 1 had been) and then file descriptor 1 would be associated
with file `fname`.
The `|&` command separator described in [Simple Commands &
Pipelines](Shell-Grammar.html#Simple-Commands-_0026-Pipelines) is a
shorthand for `2>&1 |`.
The various forms of process substitution, `<(``list``)`, and
`=(``list``)` for input and `>(``list``)` for output, are often
used together with redirection. For example, if `word` in an output
redirection is of the form `>(``list``)` then the output is piped to
the command represented by `list`. See [Process
Substitution](Expansion.html#Process-Substitution).
-----
<span id="Opening-file-descriptors-using-parameters"></span>
## 7.1 Opening file descriptors using parameters
<span id="index-file-descriptors_002c-use-with-parameters"></span>
<span id="index-parameters_002c-for-using-file-descriptors"></span>
When the shell is parsing arguments to a command, and the shell option
`IGNORE_BRACES` is not set, a different form of redirection is allowed:
instead of a digit before the operator there is a valid shell identifier
enclosed in braces. The shell will open a new file descriptor that is
guaranteed to be at least 10 and set the parameter named by the
identifier to the file descriptor opened. No whitespace is allowed
between the closing brace and the redirection character. For example:
> ... `{myfd}>&1`
This opens a new file descriptor that is a duplicate of file descriptor
1 and sets the parameter `myfd` to the number of the file descriptor,
which will be at least 10. The new file descriptor can be written to
using the syntax `>&$myfd`. The file descriptor remains open in
subshells
The syntax `{``varid``}>&-`, for example `{myfd}>&-`, may be used to
close a file descriptor opened in this fashion. Note that the parameter
given by `varid` must previously be set to a file descriptor in this
case.
It is an error to open or close a file descriptor in this fashion when
the parameter is readonly. However, it is not an error to read or write
a file descriptor using `<&$``param` or `>&$``param` if `param` is
readonly.
If the option `CLOBBER` is unset, it is an error to open a file
descriptor using a parameter that is already set to an open file
descriptor previously allocated by this mechanism. Unsetting the
parameter before using it for allocating a file descriptor avoids the
error.
Note that this mechanism merely allocates or closes a file descriptor;
it does not perform any redirections from or to it. It is usually
convenient to allocate a file descriptor prior to use as an argument to
`exec`. The syntax does not in any case work when used around complex
commands such as parenthesised subshells or loops, where the opening
brace is interpreted as part of a command list to be executed in the
current shell.
The following shows a typical sequence of allocation, use, and closing
of a file descriptor:
<div class="example">
``` example
integer myfd
exec {myfd}>~/logs/mylogfile.txt
print This is a log message. >&$myfd
exec {myfd}>&-
```
</div>
Note that the expansion of the variable in the expression `>&$myfd`
occurs at the point the redirection is opened. This is after the
expansion of command arguments and after any redirections to the left on
the command line have been processed.
-----
<span id="Multios"></span>
## 7.2 Multios
<span id="index-multios"></span>
<span id="index-MULTIOS_002c-use-of"></span>
If the user tries to open a file descriptor for writing more than once,
the shell opens the file descriptor as a pipe to a process that copies
its input to all the specified outputs, similar to tee, provided the
`MULTIOS` option is set, as it is by default. Thus:
<div class="example">
``` example
date >foo >bar
```
</div>
writes the date to two files, named `foo` and `bar`. Note that a
pipe is an implicit redirection; thus
<div class="example">
``` example
date >foo | cat
```
</div>
writes the date to the file `foo`, and also pipes it to cat.
Note that the shell opens all the files to be used in the multio process
immediately, not at the point they are about to be written.
Note also that redirections are always expanded in order. This happens
regardless of the setting of the `MULTIOS` option, but with the option
in effect there are additional consequences. For example, the meaning of
the expression `>&1` will change after a previous redirection:
<div class="example">
``` example
date >&1 >output
```
</div>
In the case above, the `>&1` refers to the standard output at the start
of the line; the result is similar to the `tee` command. However,
consider:
<div class="example">
``` example
date >output >&1
```
</div>
As redirections are evaluated in order, when the `>&1` is encountered
the standard output is set to the file `output` and another copy of the
output is therefore sent to that file. This is unlikely to be what is
intended.
If the `MULTIOS` option is set, the word after a redirection operator is
also subjected to filename generation (globbing). Thus
<div class="example">
``` example
: > *
```
</div>
will truncate all files in the current directory, assuming theres at
least one. (Without the `MULTIOS` option, it would create an empty file
called `*`.) Similarly, you can do
<div class="example">
``` example
echo exit 0 >> *.sh
```
</div>
If the user tries to open a file descriptor for reading more than once,
the shell opens the file descriptor as a pipe to a process that copies
all the specified inputs to its output in the order specified, provided
the `MULTIOS` option is set. It should be noted that each file is opened
immediately, not at the point where it is about to be read: this
behaviour differs from `cat`, so if strictly standard behaviour is
needed, `cat` should be used instead.
Thus
<div class="example">
``` example
sort <foo <fubar
```
</div>
or even
<div class="example">
``` example
sort <f{oo,ubar}
```
</div>
is equivalent to `cat foo fubar | sort`.
Expansion of the redirection argument occurs at the point the
redirection is opened, at the point described above for the expansion of
the variable in `>&$myfd`.
Note that a pipe is an implicit redirection; thus
<div class="example">
``` example
cat bar | sort <foo
```
</div>
is equivalent to `cat bar foo | sort` (note the order of the inputs).
If the `MULTIOS` option is *un*set, each redirection replaces the
previous redirection for that file descriptor. However, all files
redirected to are actually opened, so
<div class="example">
``` example
echo Hello > bar > baz
```
</div>
when `MULTIOS` is unset will truncate `bar`, and write `Hello` into
`baz`.
There is a problem when an output multio is attached to an external
program. A simple example shows this:
<div class="example">
``` example
cat file >file1 >file2
cat file1 file2
```
</div>
Here, it is possible that the second `cat` will not display the full
contents of `file1` and `file2` (i.e. the original contents of `file`
repeated twice).
The reason for this is that the multios are spawned after the `cat`
process is forked from the parent shell, so the parent shell does not
wait for the multios to finish writing data. This means the command as
shown can exit before `file1` and `file2` are completely written. As a
workaround, it is possible to run the `cat` process as part of a job in
the current shell:
<div class="example">
``` example
{ cat file } >file >file2
```
</div>
Here, the `{``...``}` job will pause to wait for both files to be
written.
-----
<span id="Redirections-with-no-command"></span>
## 7.3 Redirections with no command
When a simple command consists of one or more redirection operators and
zero or more parameter assignments, but no command name, zsh can behave
in several ways.
<span id="index-NULLCMD_002c-use-of"></span>
<span id="index-CSH_005fNULLCMD_002c-use-of"></span>
If the parameter `NULLCMD` is not set or the option `CSH_NULLCMD` is
set, an error is caused. This is the csh behavior and `CSH_NULLCMD` is
set by default when emulating csh.
<span id="index-SH_005fNULLCMD_002c-use-of"></span>
If the option `SH_NULLCMD` is set, the builtin `:` is inserted as a
command with the given redirections. This is the default when emulating
sh or ksh.
<span id="index-READNULLCMD_002c-use-of"></span>
Otherwise, if the parameter `NULLCMD` is set, its value will be used as
a command with the given redirections. If both `NULLCMD` and
`READNULLCMD` are set, then the value of the latter will be used instead
of that of the former when the redirection is an input. The default for
`NULLCMD` is `cat` and for `READNULLCMD` is `more`. Thus
<div class="example">
``` example
< file
```
</div>
shows the contents of `file` on standard output, with paging if that is
a terminal. `NULLCMD` and `READNULLCMD` may refer to shell functions.
-----
This document was generated on *February 15, 2020* using
[*texi2html 5.0*](http://www.nongnu.org/texi2html/).
Zsh version 5.8, released on February 14, 2020.

245
src/Roadmap.md Normal file
View File

@ -0,0 +1,245 @@
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [3 Roadmap](#3-roadmap)
- [3.1 When the shell starts](#31-when-the-shell-starts)
- [3.2 Interactive Use](#32-interactive-use)
- [3.2.1 Completion](#321-completion)
- [3.2.2 Extending the line editor](#322-extending-the-line-editor)
- [3.3 Options](#33-options)
- [3.4 Pattern Matching](#34-pattern-matching)
- [3.5 General Comments on Syntax](#35-general-comments-on-syntax)
- [3.6 Programming](#36-programming)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<span id="Roadmap"></span> <span id="Roadmap-1"></span>
# 3 Roadmap
<span id="index-roadmap"></span>
The Zsh Manual, like the shell itself, is large and often complicated.
This section of the manual provides some pointers to areas of the shell
that are likely to be of particular interest to new users, and indicates
where in the rest of the manual the documentation is to be found.
-----
<span id="When-the-shell-starts"></span>
## 3.1 When the shell starts
When it starts, the shell reads commands from various files. These can
be created or edited to customize the shell. See
[Files](Files.html#Files).
If no personal initialization files exist for the current user, a
function is run to help you change some of the most common settings. It
wont appear if your administrator has disabled the `zsh/newuser`
module. The function is designed to be self-explanatory. You can run it
by hand with `autoload -Uz zsh-newuser-install; zsh-newuser-install
-f`. See also [User Configuration
Functions](User-Contributions.html#User-Configuration-Functions).
-----
<span id="Interactive-Use"></span>
## 3.2 Interactive Use
Interaction with the shell uses the builtin Zsh Line Editor, ZLE. This
is described in detail in [Zsh Line
Editor](Zsh-Line-Editor.html#Zsh-Line-Editor).
The first decision a user must make is whether to use the Emacs or Vi
editing mode as the keys for editing are substantially different. Emacs
editing mode is probably more natural for beginners and can be selected
explicitly with the command `bindkey -e`.
A history mechanism for retrieving previously typed lines (most simply
with the Up or Down arrow keys) is available; note that, unlike other
shells, zsh will not save these lines when the shell exits unless you
set appropriate variables, and the number of history lines retained by
default is quite small (30 lines). See the description of the shell
variables (referred to in the documentation as parameters) `HISTFILE`,
`HISTSIZE` and `SAVEHIST` in [Parameters Used By The
Shell](Parameters.html#Parameters-Used-By-The-Shell). Note that its
currently only possible to read and write files saving history when the
shell is interactive, i.e. it does not work from scripts.
The shell now supports the UTF-8 character set (and also others if
supported by the operating system). This is (mostly) handled
transparently by the shell, but the degree of support in terminal
emulators is variable. There is some discussion of this in the shell
FAQ, `http://www.zsh.org/FAQ/`. Note in particular that for combining
characters to be handled the option `COMBINING_CHARS` needs to be set.
Because the shell is now more sensitive to the definition of the
character set, note that if you are upgrading from an older version of
the shell you should ensure that the appropriate variable, either `LANG`
(to affect all aspects of the shells operation) or `LC_CTYPE` (to
affect only the handling of character sets) is set to an appropriate
value. This is true even if you are using a single-byte character set
including extensions of ASCII such as `ISO-8859-1` or `ISO-8859-15`. See
the description of `LC_CTYPE` in
[Parameters](Parameters.html#Parameters).
-----
<span id="Completion-1"></span>
### 3.2.1 Completion
Completion is a feature present in many shells. It allows the user to
type only a part (usually the prefix) of a word and have the shell fill
in the rest. The completion system in zsh is programmable. For example,
the shell can be set to complete email addresses in arguments to the
mail command from your `~/.abook/addressbook`; usernames, hostnames, and
even remote paths in arguments to scp, and so on. Anything that can be
written in or glued together with zsh can be the source of what the line
editor offers as possible completions.
Zsh has two completion systems, an old, so called `compctl` completion
(named after the builtin command that serves as its complete and only
user interface), and a new one, referred to as `compsys`, organized as
library of builtin and user-defined functions. The two systems differ in
their interface for specifying the completion behavior. The new system
is more customizable and is supplied with completions for many commonly
used commands; it is therefore to be preferred.
The completion system must be enabled explicitly when the shell starts.
For more information see [Completion
System](Completion-System.html#Completion-System).
-----
<span id="Extending-the-line-editor"></span>
### 3.2.2 Extending the line editor
Apart from completion, the line editor is highly extensible by means of
shell functions. Some useful functions are provided with the shell; they
provide facilities such as:
- `insert-composed-char`
composing characters not found on the keyboard
- `match-words-by-style`
configuring what the line editor considers a word when moving or
deleting by word
- `history-beginning-search-backward-end`, etc.
alternative ways of searching the shell history
- `replace-string`, `replace-pattern`
functions for replacing strings or patterns globally in the command
line
- `edit-command-line`
edit the command line with an external editor.
See [ZLE Functions](User-Contributions.html#ZLE-Functions) for
descriptions of these.
-----
<span id="Options-3"></span>
## 3.3 Options
The shell has a large number of options for changing its behaviour.
These cover all aspects of the shell; browsing the full documentation is
the only good way to become acquainted with the many possibilities. See
[Options](Options.html#Options).
-----
<span id="Pattern-Matching"></span>
## 3.4 Pattern Matching
The shell has a rich set of patterns which are available for file
matching (described in the documentation as filename generation and
also known for historical reasons as globbing) and for use when
programming. These are described in [Filename
Generation](Expansion.html#Filename-Generation).
Of particular interest are the following patterns that are not commonly
supported by other systems of pattern matching:
- `**`
for matching over multiple directories
- `|`
for matching either of two alternatives
- `~`, `^`
the ability to exclude patterns from matching when the
`EXTENDED_GLOB` option is set
- `(``...``)`
glob qualifiers, included in parentheses at the end of the pattern,
which select files by type (such as directories) or attribute (such
as size).
-----
<span id="General-Comments-on-Syntax"></span>
## 3.5 General Comments on Syntax
Although the syntax of zsh is in ways similar to the Korn shell, and
therefore more remotely to the original UNIX shell, the Bourne shell,
its default behaviour does not entirely correspond to those shells.
General shell syntax is introduced in [Shell
Grammar](Shell-Grammar.html#Shell-Grammar).
One commonly encountered difference is that variables substituted onto
the command line are not split into words. See the description of the
shell option `SH_WORD_SPLIT` in [Parameter
Expansion](Expansion.html#Parameter-Expansion). In zsh, you can either
explicitly request the splitting (e.g. `${=foo}`) or use an array when
you want a variable to expand to more than one word. See [Array
Parameters](Parameters.html#Array-Parameters).
-----
<span id="Programming"></span>
## 3.6 Programming
The most convenient way of adding enhancements to the shell is typically
by writing a shell function and arranging for it to be autoloaded.
Functions are described in [Functions](Functions.html#Functions). Users
changing from the C shell and its relatives should notice that aliases
are less used in zsh as they dont perform argument substitution, only
simple text replacement.
A few general functions, other than those for the line editor described
above, are provided with the shell and are described in [User
Contributions](User-Contributions.html#User-Contributions). Features
include:
- `promptinit`
a prompt theme system for changing prompts easily, see [Prompt
Themes](User-Contributions.html#Prompt-Themes)
- `zsh-mime-setup`
a MIME-handling system which dispatches commands according to the
suffix of a file as done by graphical file managers
- `zcalc`
a calculator
- `zargs`
a version of `xargs` that makes the `find` command redundant
- `zmv`
a command for renaming files by means of shell patterns.
-----
This document was generated on *February 15, 2020* using
[*texi2html 5.0*](http://www.nongnu.org/texi2html/).
Zsh version 5.8, released on February 14, 2020.

28
src/SUMMARY.md Normal file
View File

@ -0,0 +1,28 @@
# Summary
- [The Z Shell Manual](./The-Z-Shell-Manual.md)
- [Introduction](./Introduction.md)
- [Roadmap](./Roadmap.md)
- [Invocation](./Invocation.md)
- [Files](./Files.md)
- [Shell Grammar](./Shell-Grammar.md)
- [Redirection](./Redirection.md)
- [Command Execution](./Command-Execution.md)
- [Functions](./Functions.md)
- [Jobs & Signals](./Jobs-_0026-Signals.md)
- [Arithmetic Evaluation](./Arithmetic-Evaluation.md)
- [Conditional Expressions](./Conditional-Expressions.md)
- [Prompt Expansion](./Prompt-Expansion.md)
- [Expansion](./Expansion.md)
- [Parameters](./Parameters.md)
- [Options](./Options.md)
- [Shell Builtin Commands](./Shell-Builtin-Commands.md)
- [Zsh Line Editor](./Zsh-Line-Editor.md)
- [Completion Widgets](./Completion-Widgets.md)
- [Completion System](./Completion-System.md)
- [Completion Using compctl](./Completion-Using-compctl.md)
- [Zsh Modules](./Zsh-Modules.md)
- [Calendar Function System](./Calendar-Function-System.md)
- [TCP Function System](./TCP-Function-System.md)
- [Zftp Function System](./Zftp-Function-System.md)
- [User Contributions](./User-Contributions.md)

File diff suppressed because it is too large Load Diff

816
src/Shell-Grammar.md Normal file
View File

@ -0,0 +1,816 @@
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [6 Shell Grammar](#6-shell-grammar)
- [6.1 Simple Commands & Pipelines](#61-simple-commands--pipelines)
- [6.2 Precommand Modifiers](#62-precommand-modifiers)
- [6.3 Complex Commands](#63-complex-commands)
- [6.4 Alternate Forms For Complex Commands](#64-alternate-forms-for-complex-commands)
- [6.5 Reserved Words](#65-reserved-words)
- [6.6 Errors](#66-errors)
- [6.7 Comments](#67-comments)
- [6.8 Aliasing](#68-aliasing)
- [6.8.1 Alias difficulties](#681-alias-difficulties)
- [6.9 Quoting](#69-quoting)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<span id="Shell-Grammar"></span> <span id="Shell-Grammar-1"></span>
# 6 Shell Grammar
<span id="index-shell-grammar"></span>
<span id="index-grammar_002c-shell"></span>
-----
<span id="Simple-Commands-_0026-Pipelines"></span>
<span id="Simple-Commands-_0026-Pipelines-1"></span>
## 6.1 Simple Commands & Pipelines
<span id="index-simple-commands"></span>
<span id="index-commands_002c-simple"></span>
A *simple command* is a sequence of optional parameter assignments
followed by blank-separated words, with optional redirections
interspersed. For a description of assignment, see the beginning of
[Parameters](Parameters.html#Parameters).
The first word is the command to be executed, and the remaining words,
if any, are arguments to the command. If a command name is given, the
parameter assignments modify the environment of the command when it is
executed. The value of a simple command is its exit status, or 128 plus
the signal number if terminated by a signal. For example,
<div class="example">
``` example
echo foo
```
</div>
is a simple command with arguments.
<span id="index-pipeline"></span>
A *pipeline* is either a simple command, or a sequence of two or more
simple commands where each command is separated from the next by `|`
or `|&`. Where commands are separated by `|`, the standard output of
the first command is connected to the standard input of the next. `|&`
is shorthand for `2>&1 |`, which connects both the standard output and
the standard error of the command to the standard input of the next. The
value of a pipeline is the value of the last command, unless the
pipeline is preceded by `!` in which case the value is the logical
inverse of the value of the last command. For example,
<div class="example">
``` example
echo foo | sed 's/foo/bar/'
```
</div>
is a pipeline, where the output (`foo` plus a newline) of the first
command will be passed to the input of the second.
<span id="index-coproc"></span> <span id="index-coprocess"></span>
If a pipeline is preceded by `coproc`, it is executed as a coprocess;
a two-way pipe is established between it and the parent shell. The shell
can read from or write to the coprocess by means of the `>&p` and
`<&p` redirection operators or with `print -p` and `read -p`. A
pipeline cannot be preceded by both `coproc` and `!`. If job control
is active, the coprocess can be treated in other than input and output
as an ordinary background job.
<span id="index-sublist"></span>
A *sublist* is either a single pipeline, or a sequence of two or more
pipelines separated by `&&` or `||`. If two pipelines are separated
by `&&`, the second pipeline is executed only if the first succeeds
(returns a zero status). If two pipelines are separated by `||`, the
second is executed only if the first fails (returns a nonzero status).
Both operators have equal precedence and are left associative. The value
of the sublist is the value of the last pipeline executed. For example,
<div class="example">
``` example
dmesg | grep panic && print yes
```
</div>
is a sublist consisting of two pipelines, the second just a simple
command which will be executed if and only if the `grep` command returns
a zero status. If it does not, the value of the sublist is that return
status, else it is the status returned by the `print` (almost certainly
zero).
<span id="index-list"></span>
A *list* is a sequence of zero or more sublists, in which each sublist
is terminated by `;`, `&`, `&|`, `&!`, or a newline. This
terminator may optionally be omitted from the last sublist in the list
when the list appears as a complex command inside `(`...`)` or
`{`...`}`. When a sublist is terminated by `;` or newline, the
shell waits for it to finish before executing the next sublist. If a
sublist is terminated by a `&`, `&|`, or `&!`, the shell executes
the last pipeline in it in the background, and does not wait for it to
finish (note the difference from other shells which execute the whole
sublist in the background). A backgrounded pipeline returns a status of
zero.
More generally, a list can be seen as a set of any shell commands
whatsoever, including the complex commands below; this is implied
wherever the word list appears in later descriptions. For example, the
commands in a shell function form a special sort of list.
-----
<span id="Precommand-Modifiers"></span>
<span id="Precommand-Modifiers-1"></span>
## 6.2 Precommand Modifiers
<span id="index-precommand-modifiers"></span>
<span id="index-modifiers_002c-precommand"></span>
A simple command may be preceded by a *precommand modifier*, which will
alter how the command is interpreted. These modifiers are shell builtin
commands with the exception of `nocorrect` which is a reserved word.
<span id="index-_002d"></span>
`-`
The command is executed with a `-` prepended to its `argv[0]` string.
<span id="index-builtin"></span>
`builtin`
The command word is taken to be the name of a builtin command, rather
than a shell function or external command.
<span id="index-command"></span>
`command` \[ `-pvV` \]
The command word is taken to be the name of an external command, rather
than a shell function or builtin. If the `POSIX_BUILTINS` option is set,
builtins will also be executed but certain special properties of them
are suppressed. The `-p` flag causes a default path to be searched
instead of that in `$path`. With the `-v` flag, `command` is similar to
`whence` and with `-V`, it is equivalent to `whence -v`.
<span id="index-exec"></span>
`exec` \[ `-cl` \] \[ `-a` `argv0` \]
The following command together with any arguments is run in place of the
current process, rather than as a sub-process. The shell does not fork
and is replaced. The shell does not invoke `TRAPEXIT`, nor does it
source `zlogout` files. The options are provided for compatibility with
other shells.
The `-c` option clears the environment.
The `-l` option is equivalent to the `-` precommand modifier, to treat
the replacement command as a login shell; the command is executed with a
`-` prepended to its `argv[0]` string. This flag has no effect if used
together with the `-a` option.
The `-a` option is used to specify explicitly the `argv[0]` string (the
name of the command as seen by the process itself) to be used by the
replacement command and is directly equivalent to setting a value for
the `ARGV0` environment variable.
<span id="index-nocorrect"></span>
`nocorrect`
Spelling correction is not done on any of the words. This must appear
before any other precommand modifier, as it is interpreted immediately,
before any parsing is done. It has no effect in non-interactive shells.
<span id="index-noglob"></span>
`noglob`
Filename generation (globbing) is not performed on any of the words.
-----
<span id="Complex-Commands"></span>
<span id="Complex-Commands-1"></span>
## 6.3 Complex Commands
<span id="index-complex-commands"></span>
<span id="index-commands_002c-complex"></span>
A *complex command* in zsh is one of the following:
<span id="index-if"></span> <span id="index-if-construct"></span>
`if` `list` `then` `list` \[ `elif` `list` `then` `list` \] ... \[
`else` `list` \] `fi`
The `if` `list` is executed, and if it returns a zero exit status, the
`then` `list` is executed. Otherwise, the `elif` `list` is executed and
if its status is zero, the `then` `list` is executed. If each `elif`
`list` returns nonzero status, the `else` `list` is executed.
<span id="index-for"></span> <span id="index-for-loops"></span>
<span id="index-loops_002c-for"></span>
`for` `name` ... \[ `in` `word` ... \] `term` `do` `list` `done`
Expand the list of `word`s, and set the parameter `name` to each of them
in turn, executing `list` each time. If the `in` `word` is omitted,
use the positional parameters instead of the `word`s.
The `term` consists of one or more newline or `;` which terminate the
`word`s, and are optional when the `in` `word` is omitted.
More than one parameter `name` can appear before the list of `word`s. If
`N` `name`s are given, then on each execution of the loop the next `N`
`word`s are assigned to the corresponding parameters. If there are more
`name`s than remaining `word`s, the remaining parameters are each set to
the empty string. Execution of the loop ends when there is no remaining
`word` to assign to the first `name`. It is only possible for `in` to
appear as the first `name` in the list, else it will be treated as
marking the end of the list.
`for ((` \[`expr1`\] `;` \[`expr2`\] `;` \[`expr3`\] `)) do` `list`
`done`
The arithmetic expression `expr1` is evaluated first (see [Arithmetic
Evaluation](Arithmetic-Evaluation.html#Arithmetic-Evaluation)). The
arithmetic expression `expr2` is repeatedly evaluated until it evaluates
to zero and when non-zero, `list` is executed and the arithmetic
expression `expr3` evaluated. If any expression is omitted, then it
behaves as if it evaluated to 1.
<span id="index-while"></span> <span id="index-while-loops"></span>
<span id="index-loops_002c-while"></span>
`while` `list` `do` `list` `done`
Execute the `do` `list` as long as the `while` `list` returns a zero
exit status.
<span id="index-until"></span> <span id="index-until-loops"></span>
<span id="index-loops_002c-until"></span>
`until` `list` `do` `list` `done`
Execute the `do` `list` as long as `until` `list` returns a nonzero exit
status.
<span id="index-repeat"></span> <span id="index-repeat-loops"></span>
<span id="index-loops_002c-repeat"></span>
`repeat` `word` `do` `list` `done`
`word` is expanded and treated as an arithmetic expression, which must
evaluate to a number `n`. `list` is then executed `n` times.
The `repeat` syntax is disabled by default when the shell starts in a
mode emulating another shell. It can be enabled with the command
`enable -r repeat`
<span id="index-case"></span> <span id="index-case-selection"></span>
<span id="index-selection_002c-case"></span>
`case` `word` `in` \[ \[`(`\] `pattern` \[ `|` `pattern` \] ... `)`
`list` (`;;`|`;&`|`;|`) \] ... `esac`
Execute the `list` associated with the first `pattern` that matches
`word`, if any. The form of the patterns is the same as that used for
filename generation. See [Filename
Generation](Expansion.html#Filename-Generation).
Note further that, unless the `SH_GLOB` option is set, the whole pattern
with alternatives is treated by the shell as equivalent to a group of
patterns within parentheses, although white space may appear about the
parentheses and the vertical bar and will be stripped from the pattern
at those points. White space may appear elsewhere in the pattern; this
is not stripped. If the `SH_GLOB` option is set, so that an opening
parenthesis can be unambiguously treated as part of the case syntax, the
expression is parsed into separate words and these are treated as strict
alternatives (as in other shells).
If the `list` that is executed is terminated with `;&` rather than `;;`,
the following list is also executed. The rule for the terminator of the
following list `;;`, `;&` or `;|` is applied unless the `esac` is
reached.
If the `list` that is executed is terminated with `;|` the shell
continues to scan the `pattern`s looking for the next match, executing
the corresponding `list`, and applying the rule for the corresponding
terminator `;;`, `;&` or `;|`. Note that `word` is not re-expanded; all
applicable `pattern`s are tested with the same `word`.
<span id="index-select"></span> <span id="index-user-selection"></span>
<span id="index-selection_002c-user"></span>
`select` `name` \[ `in` `word` ... `term` \] `do` `list` `done`
where `term` is one or more newline or `;` to terminate the `word`s.
<span id="index-REPLY_002c-use-of"></span> Print the set of `word`s,
each preceded by a number. If the `in` `word` is omitted, use the
positional parameters. The `PROMPT3` prompt is printed and a line is
read from the line editor if the shell is interactive and that is
active, or else standard input. If this line consists of the number of
one of the listed `word`s, then the parameter `name` is set to the
`word` corresponding to this number. If this line is empty, the
selection list is printed again. Otherwise, the value of the parameter
`name` is set to null. The contents of the line read from standard input
is saved in the parameter `REPLY`. `list` is executed for each selection
until a break or end-of-file is encountered.
<span id="index-subshell"></span>
`(` `list` `)`
Execute `list` in a subshell. Traps set by the `trap` builtin are reset
to their default values while executing `list`.
`{` `list` `}`
Execute `list`.
<span id="index-always"></span> <span id="index-always-blocks"></span>
<span id="index-try-blocks"></span>
`{` `try-list` `} always {` `always-list` `}`
First execute `try-list`. Regardless of errors, or `break` or `continue`
commands encountered within `try-list`, execute `always-list`. Execution
then continues from the result of the execution of `try-list`; in other
words, any error, or `break` or `continue` command is treated in the
normal way, as if `always-list` were not present. The two chunks of code
are referred to as the try block and the always block.
Optional newlines or semicolons may appear after the `always`; note,
however, that they may *not* appear between the preceding closing brace
and the `always`.
An error in this context is a condition such as a syntax error which
causes the shell to abort execution of the current function, script, or
list. Syntax errors encountered while the shell is parsing the code do
not cause the `always-list` to be executed. For example, an erroneously
constructed `if` block in `try-list` would cause the shell to abort
during parsing, so that `always-list` would not be executed, while an
erroneous substitution such as `${*foo*}` would cause a run-time error,
after which `always-list` would be executed.
An error condition can be tested and reset with the special integer
variable `TRY_BLOCK_ERROR`. Outside an `always-list` the value is
irrelevant, but it is initialised to `-1`. Inside `always-list`, the
value is 1 if an error occurred in the `try-list`, else 0. If
`TRY_BLOCK_ERROR` is set to 0 during the `always-list`, the error
condition caused by the `try-list` is reset, and shell execution
continues normally after the end of `always-list`. Altering the value
during the `try-list` is not useful (unless this forms part of an
enclosing `always` block).
Regardless of `TRY_BLOCK_ERROR`, after the end of `always-list` the
normal shell status `$?` is the value returned from `try-list`. This
will be non-zero if there was an error, even if `TRY_BLOCK_ERROR` was
set to zero.
The following executes the given code, ignoring any errors it causes.
This is an alternative to the usual convention of protecting code by
executing it in a subshell.
<div class="example">
``` example
{
# code which may cause an error
} always {
# This code is executed regardless of the error.
(( TRY_BLOCK_ERROR = 0 ))
}
# The error condition has been reset.
```
</div>
When a `try` block occurs outside of any function, a `return` or a
`exit` encountered in `try-list` does *not* cause the execution of
`always-list`. Instead, the shell exits immediately after any `EXIT`
trap has been executed. Otherwise, a `return` command encountered in
`try-list` will cause the execution of `always-list`, just like `break`
and `continue`.
<span id="index-function"></span>
`function` `word` ... \[ `()` \] \[ `term` \] `{` `list` `}`
`word` ... `()` \[ `term` \] `{` `list` `}`
`word` ... `()` \[ `term` \] `command`
where `term` is one or more newline or `;`. Define a function which is
referenced by any one of `word`. Normally, only one `word` is provided;
multiple `word`s are usually only useful for setting traps. The body of
the function is the `list` between the `{` and `}`. See
[Functions](Functions.html#Functions).
If the option `SH_GLOB` is set for compatibility with other shells, then
whitespace may appear between the left and right parentheses when there
is a single `word`; otherwise, the parentheses will be treated as
forming a globbing pattern in that case.
In any of the forms above, a redirection may appear outside the function
body, for example
<div class="example">
``` example
func() { ... } 2>&1
```
</div>
The redirection is stored with the function and applied whenever the
function is executed. Any variables in the redirection are expanded at
the point the function is executed, but outside the function scope.
<span id="index-timing"></span> <span id="index-time"></span>
`time` \[ `pipeline` \]
The `pipeline` is executed, and timing statistics are reported on the
standard error in the form specified by the `TIMEFMT` parameter. If
`pipeline` is omitted, print statistics about the shell process and its
children.
<span id="index-conditional-expression"></span>
<span id="index-_005b_005b"></span>
`[[` `exp` `]]`
Evaluates the conditional expression `exp` and return a zero exit status
if it is true. See [Conditional
Expressions](Conditional-Expressions.html#Conditional-Expressions) for a
description of `exp`.
-----
<span id="Alternate-Forms-For-Complex-Commands"></span>
<span id="Alternate-Forms-For-Complex-Commands-1"></span>
## 6.4 Alternate Forms For Complex Commands
<span id="index-alternate-forms-for-complex-commands"></span>
<span id="index-commands_002c-alternate-forms-for-complex"></span>
Many of zshs complex commands have alternate forms. These are
non-standard and are likely not to be obvious even to seasoned shell
programmers; they should not be used anywhere that portability of shell
code is a concern.
The short versions below only work if `sublist` is of the form `{`
`list` `}` or if the `SHORT_LOOPS` option is set. For the `if`, `while`
and `until` commands, in both these cases the test part of the loop must
also be suitably delimited, such as by `[[` `...` `]]` or `((` `...`
`))`, else the end of the test will not be recognized. For the `for`,
`repeat`, `case` and `select` commands no such special form for the
arguments is necessary, but the other condition (the special form of
`sublist` or use of the `SHORT_LOOPS` option) still applies.
- `if` `list` `{` `list` `}` \[ `elif` `list` `{` `list` `}` \] ... \[
`else {` `list` `}` \]
An alternate form of `if`. The rules mean that
<div class="example">
``` example
if [[ -o ignorebraces ]] {
print yes
}
```
</div>
works, but
<div class="example">
``` example
if true { # Does not work!
print yes
}
```
</div>
does *not*, since the test is not suitably delimited.
- `if` `list` `sublist`
A short form of the alternate `if`. The same limitations on the form
of `list` apply as for the previous form.
- `for` `name` ... `(` `word` ... `)` `sublist`
A short form of `for`.
- `for` `name` ... \[ `in` `word` ... \] `term` `sublist`
where `term` is at least one newline or `;`. Another short form of
`for`.
- `for ((` \[`expr1`\] `;` \[`expr2`\] `;` \[`expr3`\] `))`
`sublist`
A short form of the arithmetic `for` command.
<span id="index-foreach"></span>
- `foreach` `name` ... `(` `word` ... `)` `list` `end`
Another form of `for`.
- `while` `list` `{` `list` `}`
An alternative form of `while`. Note the limitations on the form of
`list` mentioned above.
- `until` `list` `{` `list` `}`
An alternative form of `until`. Note the limitations on the form of
`list` mentioned above.
- `repeat` `word` `sublist`
This is a short form of `repeat`.
- `case` `word` `{` \[ \[`(`\] `pattern` \[ `|` `pattern` \] ... `)`
`list` (`;;`|`;&`|`;|`) \] ... `}`
An alternative form of `case`.
- `select` `name` \[ `in` `word` ... `term` \] `sublist`
where `term` is at least one newline or `;`. A short form of
`select`.
- `function` `word` ... \[ `()` \] \[ `term` \] `sublist`
This is a short form of `function`.
-----
<span id="Reserved-Words"></span> <span id="Reserved-Words-1"></span>
## 6.5 Reserved Words
<span id="index-reserved-words"></span>
<span id="index-disable_002c-use-of"></span>
The following words are recognized as reserved words when used as the
first word of a command unless quoted or disabled using `disable -r`:
`do done esac then elif else fi for case if while function repeat time
until select coproc nocorrect foreach end ! [[ { } declare export float
integer local readonly typeset`
Additionally, `}` is recognized in any position if neither the
`IGNORE_BRACES` option nor the `IGNORE_CLOSE_BRACES` option is set.
-----
<span id="Errors"></span> <span id="Errors-1"></span>
## 6.6 Errors
<span id="index-errors_002c-handling-of"></span>
Certain errors are treated as fatal by the shell: in an interactive
shell, they cause control to return to the command line, and in a
non-interactive shell they cause the shell to be aborted. In older
versions of zsh, a non-interactive shell running a script would not
abort completely, but would resume execution at the next command to be
read from the script, skipping the remainder of any functions or shell
constructs such as loops or conditions; this somewhat illogical
behaviour can be recovered by setting the option `CONTINUE_ON_ERROR`.
Fatal errors found in non-interactive shells include:
- Failure to parse shell options passed when invoking the shell
- Failure to change options with the `set` builtin
- Parse errors of all sorts, including failures to parse mathematical
expressions
- Failures to set or modify variable behaviour with `typeset`,
`local`, `declare`, `export`, `integer`, `float`
- Execution of incorrectly positioned loop control structures
(`continue`, `break`)
- Attempts to use regular expression with no regular expression module
available
- Disallowed operations when the `RESTRICTED` options is set
- Failure to create a pipe needed for a pipeline
- Failure to create a multio
- Failure to autoload a module needed for a declared shell feature
- Errors creating command or process substitutions
- Syntax errors in glob qualifiers
- File generation errors where not caught by the option `BAD_PATTERN`
- All bad patterns used for matching within case statements
- File generation failures where not caused by `NO_MATCH` or similar
options
- All file generation errors where the pattern was used to create a
multio
- Memory errors where detected by the shell
- Invalid subscripts to shell variables
- Attempts to assign read-only variables
- Logical errors with variables such as assignment to the wrong type
- Use of invalid variable names
- Errors in variable substitution syntax
- Failure to convert characters in `$`...`` expressions
If the `POSIX_BUILTINS` option is set, more errors associated with shell
builtin commands are treated as fatal, as specified by the POSIX
standard.
-----
<span id="Comments"></span> <span id="Comments-1"></span>
## 6.7 Comments
<span id="index-comments"></span>
<span id="index-INTERACTIVE_005fCOMMENTS_002c-use-of"></span>
<span id="index-histchars_002c-use-of"></span>
In non-interactive shells, or in interactive shells with the
`INTERACTIVE_COMMENTS` option set, a word beginning with the third
character of the `histchars` parameter (`#` by default) causes that
word and all the following characters up to a newline to be ignored.
-----
<span id="Aliasing"></span> <span id="Aliasing-1"></span>
## 6.8 Aliasing
<span id="index-aliasing"></span>
Every eligible *word* in the shell input is checked to see if there is
an alias defined for it. If so, it is replaced by the text of the alias
if it is in command position (if it could be the first word of a simple
command), or if the alias is global. If the replacement text ends with a
space, the next word in the shell input is always eligible for purposes
of alias expansion. <span id="index-alias_002c-use-of"></span>
<span id="index-aliases_002c-global"></span> An alias is defined using
the `alias` builtin; global aliases may be defined using the `-g` option
to that builtin.
A *word* is defined as:
- Any plain string or glob pattern
- Any quoted string, using any quoting method (note that the quotes
must be part of the alias definition for this to be eligible)
- Any parameter reference or command substitution
- Any series of the foregoing, concatenated without whitespace or
other tokens between them
- Any reserved word (`case`, `do`, `else`, etc.)
- With global aliasing, any command separator, any redirection
operator, and `(` or `)` when not part of a glob pattern
Alias expansion is done on the shell input before any other expansion
except history expansion. Therefore, if an alias is defined for the word
`foo`, alias expansion may be avoided by quoting part of the word, e.g.
`\foo`. Any form of quoting works, although there is nothing to prevent
an alias being defined for the quoted form such as `\foo` as well.
When `POSIX_ALIASES` is set, only plain unquoted strings are eligible
for aliasing. The `alias` builtin does not reject ineligible aliases,
but they are not expanded.
For use with completion, which would remove an initial backslash
followed by a character that isnt special, it may be more convenient to
quote the word by starting with a single quote, i.e. `foo`; completion
will automatically add the trailing single quote.
-----
<span id="Alias-difficulties"></span>
### 6.8.1 Alias difficulties
Although aliases can be used in ways that bend normal shell syntax, not
every string of non-white-space characters can be used as an alias.
Any set of characters not listed as a word above is not a word, hence no
attempt is made to expand it as an alias, no matter how it is defined
(i.e. via the builtin or the special parameter `aliases` described in
[The zsh/parameter
Module](Zsh-Modules.html#The-zsh_002fparameter-Module)). However, as
noted in the case of `POSIX_ALIASES` above, the shell does not attempt
to deduce whether the string corresponds to a word at the time the alias
is created.
For example, an expression containing an `=` at the start of a command
line is an assignment and cannot be expanded as an alias; a lone `=` is
not an assignment but can only be set as an alias using the parameter,
as otherwise the `=` is taken part of the syntax of the builtin command.
It is not presently possible to alias the `((` token that introduces
arithmetic expressions, because until a full statement has been parsed,
it cannot be distinguished from two consecutive `(` tokens introducing
nested subshells. Also, if a separator such as `&&` is aliased, `\&&`
turns into the two tokens `\&` and `&`, each of which may have been
aliased separately. Similarly for `\<<`, `\>|`, etc.
There is a commonly encountered problem with aliases illustrated by the
following code:
<div class="example">
``` example
alias echobar='echo bar'; echobar
```
</div>
This prints a message that the command `echobar` could not be found.
This happens because aliases are expanded when the code is read in; the
entire line is read in one go, so that when `echobar` is executed it is
too late to expand the newly defined alias. This is often a problem in
shell scripts, functions, and code executed with `source` or `.`.
Consequently, use of functions rather than aliases is recommended in
non-interactive code.
Note also the unhelpful interaction of aliases and function definitions:
<div class="example">
``` example
alias func='noglob func'
func() {
echo Do something with $*
}
```
</div>
Because aliases are expanded in function definitions, this causes the
following command to be executed:
<div class="example">
``` example
noglob func() {
echo Do something with $*
}
```
</div>
which defines `noglob` as well as `func` as functions with the body
given. To avoid this, either quote the name `func` or use the
alternative function definition form `function func`. Ensuring the
alias is defined after the function works but is problematic if the code
fragment might be re-executed.
-----
<span id="Quoting"></span> <span id="Quoting-1"></span>
## 6.9 Quoting
<span id="index-quoting"></span>
A character may be *quoted* (that is, made to stand for itself) by
preceding it with a `\`. `\` followed by a newline is ignored.
A string enclosed between `$` and `` is processed the same way as
the string arguments of the `print` builtin, and the resulting string is
considered to be entirely quoted. A literal `` character can be
included in the string by using the `\` escape.
<span id="index-RC_005fQUOTES_002c-use-of"></span>
All characters enclosed between a pair of single quotes (``) that is
not preceded by a `$` are quoted. A single quote cannot appear within
single quotes unless the option `RC_QUOTES` is set, in which case a pair
of single quotes are turned into a single quote. For example,
<div class="example">
``` example
print ''''
```
</div>
outputs nothing apart from a newline if `RC_QUOTES` is not set, but one
single quote if it is set.
Inside double quotes (`""`), parameter and command substitution occur,
and `\` quotes the characters `\`, ``, `"`, `$`, and the
first character of `$histchars` (default `!`).
-----
This document was generated on *February 15, 2020* using
[*texi2html 5.0*](http://www.nongnu.org/texi2html/).
Zsh version 5.8, released on February 14, 2020.

View File

@ -0,0 +1,90 @@
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [Style and Tag Index](#style-and-tag-index)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<span id="Style-and-Tag-Index"></span>
<span id="Style-and-Tag-Index-1"></span>
# Style and Tag Index
 
[**A**](#Style-and-Tag-Index-1_ky_letter-A)  
[**B**](#Style-and-Tag-Index-1_ky_letter-B)  
[**C**](#Style-and-Tag-Index-1_ky_letter-C)  
[**D**](#Style-and-Tag-Index-1_ky_letter-D)  
[**E**](#Style-and-Tag-Index-1_ky_letter-E)  
[**F**](#Style-and-Tag-Index-1_ky_letter-F)  
[**G**](zsh_18.html#index_split-17_ky_letter-G)  
[**H**](zsh_18.html#index_split-17_ky_letter-H)  
[**I**](zsh_18.html#index_split-17_ky_letter-I)  
[**J**](zsh_18.html#index_split-17_ky_letter-J)  
[**K**](zsh_18.html#index_split-17_ky_letter-K)  
[**L**](zsh_18.html#index_split-17_ky_letter-L)  
[**M**](zsh_18.html#index_split-17_ky_letter-M)  
[**N**](zsh_18.html#index_split-17_ky_letter-N)  
[**O**](zsh_18.html#index_split-17_ky_letter-O)  
[**P**](zsh_18.html#index_split-17_ky_letter-P)  
[**Q**](zsh_19.html#index_split-18_ky_letter-Q)  
[**R**](zsh_19.html#index_split-18_ky_letter-R)  
[**S**](zsh_19.html#index_split-18_ky_letter-S)  
[**T**](zsh_19.html#index_split-18_ky_letter-T)  
[**U**](zsh_19.html#index_split-18_ky_letter-U)  
[**V**](zsh_19.html#index_split-18_ky_letter-V)  
[**W**](zsh_19.html#index_split-18_ky_letter-W)  
[**Z**](zsh_19.html#index_split-18_ky_letter-Z)  
Index Entry
 
Section
<span id="Style-and-Tag-Index-1_ky_symbol-1">-</span>
<span id="Style-and-Tag-Index-1_ky_letter-A">A</span>
<span id="Style-and-Tag-Index-1_ky_letter-B">B</span>
<span id="Style-and-Tag-Index-1_ky_letter-C">C</span>
<span id="Style-and-Tag-Index-1_ky_letter-D">D</span>
<span id="Style-and-Tag-Index-1_ky_letter-E">E</span>
<span id="Style-and-Tag-Index-1_ky_letter-F">F</span>
 
[**A**](#Style-and-Tag-Index-1_ky_letter-A)  
[**B**](#Style-and-Tag-Index-1_ky_letter-B)  
[**C**](#Style-and-Tag-Index-1_ky_letter-C)  
[**D**](#Style-and-Tag-Index-1_ky_letter-D)  
[**E**](#Style-and-Tag-Index-1_ky_letter-E)  
[**F**](#Style-and-Tag-Index-1_ky_letter-F)  
[**G**](zsh_18.html#index_split-17_ky_letter-G)  
[**H**](zsh_18.html#index_split-17_ky_letter-H)  
[**I**](zsh_18.html#index_split-17_ky_letter-I)  
[**J**](zsh_18.html#index_split-17_ky_letter-J)  
[**K**](zsh_18.html#index_split-17_ky_letter-K)  
[**L**](zsh_18.html#index_split-17_ky_letter-L)  
[**M**](zsh_18.html#index_split-17_ky_letter-M)  
[**N**](zsh_18.html#index_split-17_ky_letter-N)  
[**O**](zsh_18.html#index_split-17_ky_letter-O)  
[**P**](zsh_18.html#index_split-17_ky_letter-P)  
[**Q**](zsh_19.html#index_split-18_ky_letter-Q)  
[**R**](zsh_19.html#index_split-18_ky_letter-R)  
[**S**](zsh_19.html#index_split-18_ky_letter-S)  
[**T**](zsh_19.html#index_split-18_ky_letter-T)  
[**U**](zsh_19.html#index_split-18_ky_letter-U)  
[**V**](zsh_19.html#index_split-18_ky_letter-V)  
[**W**](zsh_19.html#index_split-18_ky_letter-W)  
[**Z**](zsh_19.html#index_split-18_ky_letter-Z)  
-----
This document was generated on *February 15, 2020* using
[*texi2html 5.0*](http://www.nongnu.org/texi2html/).
Zsh version 5.8, released on February 14, 2020.

996
src/TCP-Function-System.md Normal file
View File

@ -0,0 +1,996 @@
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [24 TCP Function System](#24-tcp-function-system)
- [24.1 Description](#241-description)
- [24.2 TCP User Functions](#242-tcp-user-functions)
- [24.2.1 Basic I/O](#2421-basic-io)
- [24.2.2 Session Management](#2422-session-management)
- [24.2.3 Advanced I/O](#2423-advanced-io)
- [24.2.4 One-shot file transfer](#2424-one-shot-file-transfer)
- [24.3 TCP User-defined Functions](#243-tcp-user-defined-functions)
- [24.4 TCP Utility Functions](#244-tcp-utility-functions)
- [24.5 TCP User Parameters](#245-tcp-user-parameters)
- [24.6 TCP User-defined Parameters](#246-tcp-user-defined-parameters)
- [24.7 TCP Utility Parameters](#247-tcp-utility-parameters)
- [24.8 TCP Examples](#248-tcp-examples)
- [24.9 TCP Bugs](#249-tcp-bugs)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<span id="TCP-Function-System"></span>
<span id="TCP-Function-System-1"></span>
# 24 TCP Function System
<span id="index-TCP-function-system"></span>
<span id="index-ztcp_002c-function-system-based-on"></span>
-----
<span id="Description"></span>
## 24.1 Description
A module `zsh/net/tcp` is provided to provide network I/O over TCP/IP
from within the shell; see its description in [Zsh
Modules](Zsh-Modules.html#Zsh-Modules). This manual page describes a
function suite based on the module. If the module is installed, the
functions are usually installed at the same time, in which case they
will be available for autoloading in the default function search path.
In addition to the `zsh/net/tcp` module, the `zsh/zselect` module is
used to implement timeouts on read operations. For troubleshooting tips,
consult the corresponding advice for the `zftp` functions described in
[Zftp Function System](Zftp-Function-System.html#Zftp-Function-System).
There are functions corresponding to the basic I/O operations open,
close, read and send, named `tcp_open` etc., as well as a function
`tcp_expect` for pattern match analysis of data read as input. The
system makes it easy to receive data from and send data to multiple
named sessions at once. In addition, it can be linked with the shells
line editor in such a way that input data is automatically shown at the
terminal. Other facilities available including logging, filtering and
configurable output prompts.
To use the system where it is available, it should be enough to
`autoload -U tcp_open` and run `tcp_open` as documented below to
start a session. The `tcp_open` function will autoload the remaining
functions.
-----
<span id="TCP-Functions"></span> <span id="TCP-User-Functions"></span>
## 24.2 TCP User Functions
-----
<span id="Basic-I_002fO"></span>
### 24.2.1 Basic I/O
<span id="index-tcp_005fopen"></span>
`tcp_open` \[ `-qz` \] `host port` \[ `sess` \]
`tcp_open` \[ `-qz` \] \[ `-s` `sess` | `-l` `sess`\[`,`...\] \] ...
`tcp_open` \[ `-qz` \] \[ `-a` `fd` | `-f` `fd` \] \[ `sess` \]
Open a new session. In the first and simplest form, open a TCP
connection to host `host` at port `port`; numeric and symbolic forms are
understood for both.
If `sess` is given, this becomes the name of the session which can be
used to refer to multiple different TCP connections. If `sess` is not
given, the function will invent a numeric name value (note this is *not*
the same as the file descriptor to which the session is attached). It is
recommended that session names not include funny characters, where
funny characters are not well-defined but certainly do not include
alphanumerics or underscores, and certainly do include whitespace.
In the second case, one or more sessions to be opened are given by name.
A single session name is given after `-s` and a comma-separated list
after `-l`; both options may be repeated as many times as necessary. A
failure to open any session causes `tcp_open` to abort. The host and
port are read from the file `.ztcp_sessions` in the same directory as
the users zsh initialisation files, i.e. usually the home directory,
but `$ZDOTDIR` if that is set. The file consists of lines each giving a
session name and the corresponding host and port, in that order (note
the session name comes first, not last), separated by whitespace.
The third form allows passive and fake TCP connections. If the option
`-a` is used, its argument is a file descriptor open for listening for
connections. No function front-end is provided to open such a file
descriptor, but a call to `ztcp -l` `port` will create one with the
file descriptor stored in the parameter `$REPLY`. The listening port can
be closed with `ztcp -c` `fd`. A call to `tcp_open -a` `fd` will
block until a remote TCP connection is made to `port` on the local
machine. At this point, a session is created in the usual way and is
largely indistinguishable from an active connection created with one of
the first two forms.
If the option `-f` is used, its argument is a file descriptor which is
used directly as if it were a TCP session. How well the remainder of the
TCP function system copes with this depends on what actually underlies
this file descriptor. A regular file is likely to be unusable; a FIFO
(pipe) of some sort will work better, but note that it is not a good
idea for two different sessions to attempt to read from the same FIFO at
once.
If the option `-q` is given with any of the three forms, `tcp_open` will
not print informational messages, although it will in any case exit with
an appropriate status.
If the line editor (zle) is in use, which is typically the case if the
shell is interactive, `tcp_open` installs a handler inside zle which
will check for new data at the same time as it checks for keyboard
input. This is convenient as the shell consumes no CPU time while
waiting; the test is performed by the operating system. Giving the
option `-z` to any of the forms of `tcp_open` prevents the handler from
being installed, so data must be read explicitly. Note, however, this is
not necessary for executing complete sets of send and read commands from
a function, as zle is not active at this point. Generally speaking, the
handler is only active when the shell is waiting for input at a command
prompt or in the `vared` builtin. The option has no effect if zle is not
active; `[[ -o zle]]` will test for this.
The first session to be opened becomes the current session and
subsequent calls to `tcp_open` do not change it. The current session is
stored in the parameter `$TCP_SESS`; see below for more detail about the
parameters used by the system.
The function `tcp_on_open`, if defined, is called when a session is
opened. See the description below.
<span id="index-tcp_005fclose"></span>
`tcp_close` \[ `-qn` \] \[ `-a` | `-l` `sess`\[`,`...\] | `sess` ... \]
Close the named sessions, or the current session if none is given, or
all open sessions if `-a` is given. The options `-l` and `-s` are both
handled for consistency with `tcp_open`, although the latter is
redundant.
If the session being closed is the current one, `$TCP_SESS` is unset,
leaving no current session, even if there are other sessions still open.
If the session was opened with `tcp_open -f`, the file descriptor is
closed so long as it is in the range 0 to 9 accessible directly from the
command line. If the option `-n` is given, no attempt will be made to
close file descriptors in this case. The `-n` option is not used for
genuine `ztcp` session; the file descriptors are always closed with the
session.
If the option `-q` is given, no informational messages will be printed.
<span id="index-tcp_005fread"></span>
` tcp_read `\[ `-bdq` \] \[ `-t` `TO` \] \[ `-T` `TO` \]
`         `\[ `-a` | `-u` `fd`\[`,`...\] | `-l` `sess`\[`,`...\] | `-s`
`sess` ... \]
Perform a read operation on the current session, or on a list of
sessions if any are given with `-u`, `-l` or `-s`, or all open sessions
if the option `-a` is given. Any of the `-u`, `-l` or `-s` options may
be repeated or mixed together. The `-u` option specifies a file
descriptor directly (only those managed by this system are useful), the
other two specify sessions as described for `tcp_open` above.
The function checks for new data available on all the sessions listed.
Unless the `-b` option is given, it will not block waiting for new data.
Any one line of data from any of the available sessions will be read,
stored in the parameter `$TCP_LINE`, and displayed to standard output
unless `$TCP_SILENT` contains a non-empty string. When printed to
standard output the string `$TCP_PROMPT` will be shown at the start of
the line; the default form for this includes the name of the session
being read. See below for more information on these parameters. In this
mode, `tcp_read` can be called repeatedly until it returns status 2
which indicates all pending input from all specified sessions has been
handled.
With the option `-b`, equivalent to an infinite timeout, the function
will block until a line is available to read from one of the specified
sessions. However, only a single line is returned.
The option `-d` indicates that all pending input should be drained. In
this case `tcp_read` may process multiple lines in the manner given
above; only the last is stored in `$TCP_LINE`, but the complete set is
stored in the array `$tcp_lines`. This is cleared at the start of each
call to `tcp_read`.
The options `-t` and `-T` specify a timeout in seconds, which may be a
floating point number for increased accuracy. With `-t` the timeout is
applied before each line read. With `-T`, the timeout applies to the
overall operation, possibly including multiple read operations if the
option `-d` is present; without this option, there is no distinction
between `-t` and `-T`.
The function does not print informational messages, but if the option
`-q` is given, no error message is printed for a non-existent session.
A return status of 2 indicates a timeout or no data to read. Any other
non-zero return status indicates some error condition.
See `tcp_log` for how to control where data is sent by `tcp_read`.
<span id="index-tcp_005fsend"></span>
`tcp_send` \[ `-cnq` \] \[ `-s` `sess` | `-l` `sess`\[`,`...\] \] `data`
...
`tcp_send` \[ `-cnq` \] `-a` `data` ...
Send the supplied data strings to all the specified sessions in turn.
The underlying operation differs little from a `print -r` to the
sessions file descriptor, although it attempts to prevent the shell
from dying owing to a `SIGPIPE` caused by an attempt to write to a
defunct session.
The option `-c` causes `tcp_send` to behave like `cat`. It reads lines
from standard input until end of input and sends them in turn to the
specified session(s) exactly as if they were given as `data` arguments
to individual `tcp_send` commands.
The option `-n` prevents `tcp_send` from putting a newline at the end of
the data strings.
The remaining options all behave as for `tcp_read`.
The data arguments are not further processed once they have been passed
to `tcp_send`; they are simply passed down to `print -r`.
If the parameter `$TCP_OUTPUT` is a non-empty string and logging is
enabled then the data sent to each session will be echoed to the log
file(s) with `$TCP_OUTPUT` in front where appropriate, much in the
manner of `$TCP_PROMPT`.
-----
<span id="Session-Management"></span>
### 24.2.2 Session Management
<span id="index-tcp_005falias"></span>
`tcp_alias` \[ `-q` \] `alias``=``sess` ...
`tcp_alias` \[ `-q` \] \[ `alias` ... \]
`tcp_alias` `-d` \[ `-q` \] `alias` ...
This function is not particularly well tested.
The first form creates an alias for a session name; `alias` can then be
used to refer to the existing session `sess`. As many aliases may be
listed as required.
The second form lists any aliases specified, or all aliases if none.
The third form deletes all the aliases listed. The underlying sessions
are not affected.
The option `-q` suppresses an inconsistently chosen subset of error
messages.
<span id="index-tcp_005flog"></span>
`tcp_log` \[ `-asc` \] \[ `-n` | `-N` \] \[ `logfile` \]
With an argument `logfile`, all future input from `tcp_read` will be
logged to the named file. Unless `-a` (append) is given, this file will
first be truncated or created empty. With no arguments, show the current
status of logging.
With the option `-s`, per-session logging is enabled. Input from
`tcp_read` is output to the file `logfile``.``sess`. As the session is
automatically discriminated by the filename, the contents are raw (no
`$TCP_PROMPT`). The option `-a` applies as above. Per-session logging
and logging of all data in one file are not mutually exclusive.
The option `-c` closes all logging, both complete and per-session logs.
The options `-n` and `-N` respectively turn off or restore output of
data read by `tcp_read` to standard output; hence `tcp_log -cn` turns
off all output by `tcp_read`.
The function is purely a convenient front end to setting the parameters
`$TCP_LOG`, `$TCP_LOG_SESS`, `$TCP_SILENT`, which are described below.
<span id="index-tcp_005frename"></span>
`tcp_rename` `old` `new`
Rename session `old` to session `new`. The old name becomes invalid.
<span id="index-tcp_005fsess"></span>
`tcp_sess` \[ `sess` \[ `command` \[ `arg` ... \] \] \]
With no arguments, list all the open sessions and associated file
descriptors. The current session is marked with a star. For use in
functions, direct access to the parameters `$tcp_by_name`, `$tcp_by_fd`
and `$TCP_SESS` is probably more convenient; see below.
With a `sess` argument, set the current session to `sess`. This is
equivalent to changing `$TCP_SESS` directly.
With additional arguments, temporarily set the current session while
executing `command` `arg` .... `command` is re-evaluated so as to
expand aliases etc., but the remaining `arg`s are passed through as that
appear to `tcp_sess`. The original session is restored when `tcp_sess`
exits.
-----
<span id="Advanced-I_002fO"></span>
### 24.2.3 Advanced I/O
<span id="index-tcp_005fcommand"></span>
`tcp_command` `send-option` ... `send-argument` ...
This is a convenient front-end to `tcp_send`. All arguments are passed
to `tcp_send`, then the function pauses waiting for data. While data is
arriving at least every `$TCP_TIMEOUT` (default 0.3) seconds, data is
handled and printed out according to the current settings. Status 0 is
always returned.
This is generally only useful for interactive use, to prevent the
display becoming fragmented by output returned from the connection.
Within a programme or function it is generally better to handle reading
data by a more explicit method.
<span id="index-tcp_005fexpect"></span>
` tcp_expect `\[ `-q` \] \[ `-p` `var` | `-P` `var` \] \[ `-t` `TO` |
`-T` `TO` \]
`           `\[ `-a` | `-s` `sess` | `-l` `sess`\[`,`...\] \] `pattern`
...
Wait for input matching any of the given `pattern`s from any of the
specified sessions. Input is ignored until an input line matches one of
the given patterns; at this point status zero is returned, the matching
line is stored in `$TCP_LINE`, and the full set of lines read during the
call to `tcp_expect` is stored in the array `$tcp_expect_lines`.
Sessions are specified in the same way as `tcp_read`: the default is to
use the current session, otherwise the sessions specified by `-a`, `-s`,
or `-l` are used.
Each `pattern` is a standard zsh extended-globbing pattern; note that it
needs to be quoted to avoid it being expanded immediately by filename
generation. It must match the full line, so to match a substring there
must be a `*` at the start and end. The line matched against includes
the `$TCP_PROMPT` added by `tcp_read`. It is possible to include the
globbing flags `#b` or `#m` in the patterns to make backreferences
available in the parameters `$MATCH`, `$match`, etc., as described in
the base zsh documentation on pattern matching.
Unlike `tcp_read`, the default behaviour of `tcp_expect` is to block
indefinitely until the required input is found. This can be modified by
specifying a timeout with `-t` or `-T`; these function as in `tcp_read`,
specifying a per-read or overall timeout, respectively, in seconds, as
an integer or floating-point number. As `tcp_read`, the function returns
status 2 if a timeout occurs.
The function returns as soon as any one of the patterns given match. If
the caller needs to know which of the patterns matched, the option `-p`
`var` can be used; on return, `$var` is set to the number of the pattern
using ordinary zsh indexing, i.e. the first is 1, and so on. Note the
absence of a `$` in front of `var`. To avoid clashes, the parameter
cannot begin with `_expect`. The index -1 is used if there is a
timeout and 0 if there is no match.
The option `-P` `var` works similarly to `-p`, but instead of numerical
indexes the regular arguments must begin with a prefix followed by a
colon: that prefix is then used as a tag to which `var` is set when the
argument matches. The tag `timeout` is used if there is a timeout and
the empty string if there is no match. Note it is matches do not need to
be distinguished.
The option `-q` is passed directly down to `tcp_read`.
As all input is done via `tcp_read`, all the usual rules about output of
lines read apply. One exception is that the parameter `$tcp_lines` will
only reflect the line actually matched by `tcp_expect`; use
`$tcp_expect_lines` for the full set of lines read during the function
call.
<span id="index-tcp_005fproxy"></span>
`tcp_proxy`
This is a simple-minded function to accept a TCP connection and execute
a command with I/O redirected to the connection. Extreme caution should
be taken as there is no security whatsoever and this can leave your
computer open to the world. Ideally, it should only be used behind a
firewall.
The first argument is a TCP port on which the function will listen.
The remaining arguments give a command and its arguments to execute with
standard input, standard output and standard error redirected to the
file descriptor on which the TCP session has been accepted. If no
command is given, a new zsh is started. This gives everyone on your
network direct access to your account, which in many cases will be a bad
thing.
The command is run in the background, so `tcp_proxy` can then accept new
connections. It continues to accept new connections until interrupted.
<span id="index-tcp_005fspam"></span>
`tcp_spam` \[ `-ertv` \] \[ `-a` | `-s` `sess` | `-l` `sess`\[`,`...\]
\] `cmd` \[ `arg` ... \]
Execute `cmd` \[ `arg` ... \] for each session in turn. Note this
executes the command and arguments; it does not send the command line as
data unless the `-t` (transmit) option is given.
The sessions may be selected explicitly with the standard `-a`, `-s` or
`-l` options, or may be chosen implicitly. If none of the three options
is given the rules are: first, if the array `$tcp_spam_list` is set,
this is taken as the list of sessions, otherwise all sessions are taken.
Second, any sessions given in the array `$tcp_no_spam_list` are removed
from the list of sessions.
Normally, any sessions added by the `-a` flag or when all sessions are
chosen implicitly are spammed in alphabetic order; sessions given by the
`$tcp_spam_list` array or on the command line are spammed in the order
given. The `-r` flag reverses the order however it was arrived it.
The `-v` flag specifies that a `$TCP_PROMPT` will be output before each
session. This is output after any modification to `TCP_SESS` by the
user-defined `tcp_on_spam` function described below. (Obviously that
function is able to generate its own output.)
If the option `-e` is present, the line given as `cmd` \[ `arg` ... \]
is executed using `eval`, otherwise it is executed without any further
processing.
<span id="index-tcp_005ftalk"></span>
`tcp_talk`
This is a fairly simple-minded attempt to force input to the line editor
to go straight to the default `TCP_SESS`.
An escape string, `$TCP_TALK_ESCAPE`, default `:`, is used to allow
access to normal shell operation. If it is on its own at the start of
the line, or followed only by whitespace, the line editor returns to
normal operation. Otherwise, the string and any following whitespace are
skipped and the remainder of the line executed as shell input without
any change of the line editors operating mode.
The current implementation is somewhat deficient in terms of use of the
command history. For this reason, many users will prefer to use some
form of alternative approach for sending data easily to the current
session. One simple approach is to alias some special character (such as
`%`) to `tcp_command -``-`.
<span id="index-tcp_005fwait"></span>
`tcp_wait`
The sole argument is an integer or floating point number which gives the
seconds to delay. The shell will do nothing for that period except wait
for input on all TCP sessions by calling `tcp_read -a`. This is similar
to the interactive behaviour at the command prompt when zle handlers are
installed.
-----
<span id="g_t_0060One_002dshot_0027-file-transfer"></span>
### 24.2.4 One-shot file transfer
- `tcp_point` `port`
`tcp_shoot` `host` `port`
This pair of functions provide a simple way to transfer a file
between two hosts within the shell. Note, however, that bulk data
transfer is currently done using `cat`. `tcp_point` reads any data
arriving at `port` and sends it to standard output; `tcp_shoot`
connects to `port` on `host` and sends its standard input. Any
unused `port` may be used; the standard mechanism for picking a port
is to think of a random four-digit number above 1024 until one
works.
To transfer a file from host `woodcock` to host `springes`, on
`springes`:
<div class="example">
``` example
tcp_point 8091 >output_file
```
</div>
and on `woodcock`:
<div class="example">
``` example
tcp_shoot springes 8091 <input_file
```
</div>
As these two functions do not require `tcp_open` to set up a TCP
connection first, they may need to be autoloaded separately.
-----
<span id="TCP-User_002ddefined-Functions"></span>
## 24.3 TCP User-defined Functions
Certain functions, if defined by the user, will be called by the
function system in certain contexts. This facility depends on the module
`zsh/parameter`, which is usually available in interactive shells as the
completion system depends on it. None of the functions need be defined;
they simply provide convenient hooks when necessary.
Typically, these are called after the requested action has been taken,
so that the various parameters will reflect the new state.
<span id="index-tcp_005fon_005falias"></span>
`tcp_on_alias` `alias` `fd`
When an alias is defined, this function will be called with two
arguments: the name of the alias, and the file descriptor of the
corresponding session.
<span id="index-tcp_005fon_005fawol"></span>
`tcp_on_awol` `sess` `fd`
If the function `tcp_fd_handler` is handling input from the line editor
and detects that the file descriptor is no longer reusable, by default
it removes it from the list of file descriptors handled by this method
and prints a message. If the function `tcp_on_awol` is defined it is
called immediately before this point. It may return status 100, which
indicates that the normal handling should still be performed; any other
return status indicates that no further action should be taken and the
`tcp_fd_handler` should return immediately with the given status.
Typically the action of `tcp_on_awol` will be to close the session.
The variable `TCP_INVALIDATE_ZLE` will be a non-empty string if it is
necessary to invalidate the line editor display using `zle -I` before
printing output from the function.
(AWOL is military jargon for absent without leave or some variation.
It has no pre-existing technical meaning known to the author.)
<span id="index-tcp_005fon_005fclose"></span>
`tcp_on_close` `sess` `fd`
This is called with the name of a session being closed and the file
descriptor which corresponded to that session. Both will be invalid by
the time the function is called.
<span id="index-tcp_005fon_005fopen"></span>
`tcp_on_open` `sess` `fd`
This is called after a new session has been defined with the session
name and file descriptor as arguments. If it returns a non-zero status,
opening the session is assumed to fail and the session is closed again;
however, `tcp_open` will continue to attempt to open any remaining
sessions given on the command line.
<span id="index-tcp_005fon_005frename"></span>
`tcp_on_rename` `oldsess` `fd` `newsess`
This is called after a session has been renamed with the three arguments
old session name, file descriptor, new session name.
<span id="index-tcp_005fon_005fspam"></span>
`tcp_on_spam` `sess` `command ...`
This is called once for each session spammed, just *before* a command is
executed for a session by `tcp_spam`. The arguments are the session name
followed by the command list to be executed. If `tcp_spam` was called
with the option `-t`, the first command will be `tcp_send`.
This function is called after `$TCP_SESS` is set to reflect the session
to be spammed, but before any use of it is made. Hence it is possible to
alter the value of `$TCP_SESS` within this function. For example, the
session arguments to `tcp_spam` could include extra information to be
stripped off and processed in `tcp_on_spam`.
If the function sets the parameter `$REPLY` to `done`, the command
line is not executed; in addition, no prompt is printed for the `-v`
option to `tcp_spam`.
<span id="index-tcp_005fon_005funalias"></span>
`tcp_on_unalias` `alias` `fd`
This is called with the name of an alias and the corresponding sessions
file descriptor after an alias has been deleted.
-----
<span id="TCP-Utility-Functions"></span>
## 24.4 TCP Utility Functions
The following functions are used by the TCP function system but will
rarely if ever need to be called directly.
<span id="index-tcp_005ffd_005fhandler"></span>
`tcp_fd_handler`
This is the function installed by `tcp_open` for handling input from
within the line editor, if that is required. It is in the format
documented for the builtin `zle -F` in [Zle
Builtins](Zsh-Line-Editor.html#Zle-Builtins) .
While active, the function sets the parameter `TCP_HANDLER_ACTIVE` to 1.
This allows shell code called internally (for example, by setting
`tcp_on_read`) to tell if is being called when the shell is otherwise
idle at the editor prompt.
<span id="index-tcp_005foutput"></span>
`tcp_output` \[ `-q` \] `-P` `prompt` `-F` `fd` `-S` `sess`
This function is used for both logging and handling output to standard
output, from within `tcp_read` and (if `$TCP_OUTPUT` is set) `tcp_send`.
The `prompt` to use is specified by `-P`; the default is the empty
string. It can contain:
- `%c`
Expands to 1 if the session is the current session, otherwise 0.
Used with ternary expressions such as `%(c.-.+)` to output `+`
for the current session and `-` otherwise.
- `%f`
Replaced by the sessions file descriptor.
- `%s`
Replaced by the session name.
- `%%`
Replaced by a single `%`.
The option `-q` suppresses output to standard output, but not to any log
files which are configured.
The `-S` and `-F` options are used to pass in the session name and file
descriptor for possible replacement in the prompt.
-----
<span id="TCP-Parameters"></span> <span id="TCP-User-Parameters"></span>
## 24.5 TCP User Parameters
Parameters follow the usual convention that uppercase is used for
scalars and integers, while lowercase is used for normal and associative
array. It is always safe for user code to read these parameters. Some
parameters may also be set; these are noted explicitly. Others are
included in this group as they are set by the function system for the
users benefit, i.e. setting them is typically not useful but is benign.
For example, `local TCP_SILENT=1` specifies that data read during the
function call will not be printed to standard output, regardless of the
setting outside the function. Likewise, `local TCP_SESS=``sess` sets a
session for the duration of a function, and `local TCP_PROMPT=`
specifies that no prompt is used for input during the function.
<span id="index-tcp_005fexpect_005flines"></span>
`tcp_expect_lines`
Array. The set of lines read during the last call to `tcp_expect`,
including the last (`$TCP_LINE`).
<span id="index-tcp_005ffilter"></span>
`tcp_filter`
Array. May be set directly. A set of extended globbing patterns which,
if matched in `tcp_output`, will cause the line not to be printed to
standard output. The patterns should be defined as described for the
arguments to `tcp_expect`. Output of line to log files is not affected.
<span id="index-TCP_005fHANDLER_005fACTIVE"></span>
`TCP_HANDLER_ACTIVE`
Scalar. Set to 1 within `tcp_fd_handler` to indicate to functions called
recursively that they have been called during an editor session.
Otherwise unset.
<span id="index-TCP_005fLINE"></span>
`TCP_LINE`
The last line read by `tcp_read`, and hence also `tcp_expect`.
<span id="index-TCP_005fLINE_005fFD"></span>
`TCP_LINE_FD`
The file descriptor from which `$TCP_LINE` was read.
`${tcp_by_fd[$TCP_LINE_FD]}` will give the corresponding session name.
<span id="index-tcp_005flines"></span>
`tcp_lines`
Array. The set of lines read during the last call to `tcp_read`,
including the last (`$TCP_LINE`).
<span id="index-TCP_005fLOG"></span>
`TCP_LOG`
May be set directly, although it is also controlled by `tcp_log`. The
name of a file to which output from all sessions will be sent. The
output is proceeded by the usual `$TCP_PROMPT`. If it is not an absolute
path name, it will follow the users current directory.
<span id="index-TCP_005fLOG_005fSESS"></span>
`TCP_LOG_SESS`
May be set directly, although it is also controlled by `tcp_log`. The
prefix for a set of files to which output from each session separately
will be sent; the full filename is `${TCP_LOG_SESS}.``sess`. Output to
each file is raw; no prompt is added. If it is not an absolute path
name, it will follow the users current directory.
<span id="index-tcp_005fno_005fspam_005flist"></span>
`tcp_no_spam_list`
Array. May be set directly. See `tcp_spam` for how this is used.
<span id="index-TCP_005fOUTPUT"></span>
`TCP_OUTPUT`
May be set directly. If a non-empty string, any data sent to a session
by `tcp_send` will be logged. This parameter gives the prompt to be used
in a file specified by `$TCP_LOG` but not in a file generated from
`$TCP_LOG_SESS`. The prompt string has the same format as `TCP_PROMPT`
and the same rules for its use apply.
<span id="index-TCP_005fPROMPT"></span>
`TCP_PROMPT`
May be set directly. Used as the prefix for data read by `tcp_read`
which is printed to standard output or to the log file given by
`$TCP_LOG`, if any. Any `%s`, `%f` or `%%` occurring in the string
will be replaced by the name of the session, the sessions underlying
file descriptor, or a single `%`, respectively. The expression `%c`
expands to 1 if the session being read is the current session, else 0;
this is most useful in ternary expressions such as `%(c.-.+)` which
outputs `+` if the session is the current one, else `-`.
If the prompt starts with `%P`, this is stripped and the complete result
of the previous stage is passed through standard prompt `%`-style
formatting before being output.
<span id="index-TCP_005fREAD_005fDEBUG"></span>
`TCP_READ_DEBUG`
May be set directly. If this has non-zero length, `tcp_read` will give
some limited diagnostics about data being read.
<span id="index-TCP_005fSECONDS_005fSTART"></span>
`TCP_SECONDS_START`
This value is created and initialised to zero by tcp\_open.
The functions `tcp_read` and `tcp_expect` use the shells `SECONDS`
parameter for their own timing purposes. If that parameter is not of
floating point type on entry to one of the functions, it will create a
local parameter `SECONDS` which is floating point and set the parameter
`TCP_SECONDS_START` to the previous value of `$SECONDS`. If the
parameter is already floating point, it is used without a local copy
being created and `TCP_SECONDS_START` is not set. As the global value is
zero, the shell elapsed time is guaranteed to be the sum of `$SECONDS`
and `$TCP_SECONDS_START`.
This can be avoided by setting `SECONDS` globally to a floating point
value using `typeset -F SECONDS`; then the TCP functions will never
make a local copy and never set `TCP_SECONDS_START` to a non-zero value.
<span id="index-TCP_005fSESS"></span>
`TCP_SESS`
May be set directly. The current session; must refer to one of the
sessions established by `tcp_open`.
<span id="index-TCP_005fSILENT"></span>
`TCP_SILENT`
May be set directly, although it is also controlled by `tcp_log`. If of
non-zero length, data read by `tcp_read` will not be written to standard
output, though may still be written to a log file.
<span id="index-tcp_005fspam_005flist"></span>
`tcp_spam_list`
Array. May be set directly. See the description of the function
`tcp_spam` for how this is used.
<span id="index-TCP_005fTALK_005fESCAPE"></span>
`TCP_TALK_ESCAPE`
May be set directly. See the description of the function `tcp_talk` for
how this is used.
<span id="index-TCP_005fTIMEOUT"></span>
`TCP_TIMEOUT`
May be set directly. Currently this is only used by the function
`tcp_command`, see above.
-----
<span id="TCP-User_002ddefined-Parameters"></span>
## 24.6 TCP User-defined Parameters
The following parameters are not set by the function system, but have a
special effect if set by the user.
<span id="index-tcp_005fon_005fread"></span>
`tcp_on_read`
This should be an associative array; if it is not, the behaviour is
undefined. Each key is the name of a shell function or other command,
and the corresponding value is a shell pattern (using `EXTENDED_GLOB`).
Every line read from a TCP session directly or indirectly using
`tcp_read` (which includes lines read by `tcp_expect`) is compared
against the pattern. If the line matches, the command given in the key
is called with two arguments: the name of the session from which the
line was read, and the line itself.
If any function called to handle a line returns a non-zero status, the
line is not output. Thus a `tcp_on_read` handler containing only the
instruction `return 1` can be used to suppress output of particular
lines (see, however, `tcp_filter` above). However, the line is still
stored in `TCP_LINE` and `tcp_lines`; this occurs after all
`tcp_on_read` processing.
-----
<span id="TCP-Utility-Parameters"></span>
## 24.7 TCP Utility Parameters
These parameters are controlled by the function system; they may be read
directly, but should not usually be set by user code.
<span id="index-tcp_005faliases"></span>
`tcp_aliases`
Associative array. The keys are the names of sessions established with
`tcp_open`; each value is a space-separated list of aliases which refer
to that session.
<span id="index-tcp_005fby_005ffd"></span>
`tcp_by_fd`
Associative array. The keys are session file descriptors; each value is
the name of that session.
<span id="index-tcp_005fby_005fname"></span>
`tcp_by_name`
Associative array. The keys are the names of sessions; each value is the
file descriptor associated with that session.
-----
<span id="TCP-Examples"></span> <span id="TCP-Examples-1"></span>
## 24.8 TCP Examples
Here is a trivial example using a remote calculator.
To create a calculator server on port 7337 (see the `dc` manual page for
quite how infuriating the underlying command is):
<div class="example">
``` example
tcp_proxy 7337 dc
```
</div>
To connect to this from the same host with a session also named `dc`:
<div class="example">
``` example
tcp_open localhost 7337 dc
```
</div>
To send a command to the remote session and wait a short while for
output (assuming `dc` is the current session):
<div class="example">
``` example
tcp_command 2 4 + p
```
</div>
To close the session:
<div class="example">
``` example
tcp_close
```
</div>
The `tcp_proxy` needs to be killed to be stopped. Note this will not
usually kill any connections which have already been accepted, and also
that the port is not immediately available for reuse.
The following chunk of code puts a list of sessions into an xterm
header, with the current session followed by a star.
<div class="example">
``` example
print -n "\033]2;TCP:" ${(k)tcp_by_name:/$TCP_SESS/$TCP_SESS\*} "\a"
```
</div>
-----
<span id="TCP-Bugs"></span> <span id="TCP-Bugs-1"></span>
## 24.9 TCP Bugs
The function `tcp_read` uses the shells normal `read` builtin. As this
reads a complete line at once, data arriving without a terminating
newline can cause the function to block indefinitely.
Though the function suite works well for interactive use and for data
arriving in small amounts, the performance when large amounts of data
are being exchanged is likely to be extremely poor.
-----
This document was generated on *February 15, 2020* using
[*texi2html 5.0*](http://www.nongnu.org/texi2html/).
Zsh version 5.8, released on February 14, 2020.

Some files were not shown because too many files have changed in this diff Show More