540 lines
30 KiB
HTML
540 lines
30 KiB
HTML
<!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 -->
|
||
<link rel="stylesheet" href="./theme/catppuccin.css">
|
||
<link rel="stylesheet" href="./theme/catppuccin-highlight.css">
|
||
|
||
</head>
|
||
<body>
|
||
<!-- Provide site root to javascript -->
|
||
<script type="text/javascript">
|
||
var path_to_root = "";
|
||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||
</script>
|
||
|
||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||
<script type="text/javascript">
|
||
try {
|
||
var theme = localStorage.getItem('mdbook-theme');
|
||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||
|
||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||
}
|
||
|
||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||
}
|
||
} catch (e) { }
|
||
</script>
|
||
|
||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||
<script type="text/javascript">
|
||
var theme;
|
||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||
var html = document.querySelector('html');
|
||
html.classList.remove('no-js')
|
||
html.classList.remove('light')
|
||
html.classList.add(theme);
|
||
html.classList.add('js');
|
||
</script>
|
||
|
||
<!-- Hide / unhide sidebar before it is displayed -->
|
||
<script type="text/javascript">
|
||
var html = document.querySelector('html');
|
||
var sidebar = 'hidden';
|
||
if (document.body.clientWidth >= 1080) {
|
||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||
sidebar = sidebar || 'visible';
|
||
}
|
||
html.classList.remove('sidebar-visible');
|
||
html.classList.add("sidebar-" + sidebar);
|
||
</script>
|
||
|
||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||
<div class="sidebar-scrollbox">
|
||
<ol class="chapter"><li class="chapter-item expanded "><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-&-Signals.html"><strong aria-hidden="true">10.</strong> Jobs & 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>
|
||
<li role="none"><button role="menuitem" class="theme" id="latte">Latte</button></li>
|
||
<li role="none"><button role="menuitem" class="theme" id="frappe">Frappé</button></li>
|
||
<li role="none"><button role="menuitem" class="theme" id="macchiato">Macchiato</button></li>
|
||
<li role="none"><button role="menuitem" class="theme" id="mocha">Mocha</button></li>
|
||
</ul>
|
||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||
<i class="fa fa-search"></i>
|
||
</button>
|
||
</div>
|
||
|
||
<h1 class="menu-title">Zsh 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" 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 & 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.</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>
|
||
<p>< <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>
|
||
<p><> <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>
|
||
<p>> <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 CLOBBER option is
|
||
unset, this causes an error; otherwise, it is truncated to zero length.</p>
|
||
<p>>| <code>word</code><br />
|
||
>! <code>word</code><br />
|
||
Same as >, except that the file is truncated to zero length if it
|
||
exists, regardless of CLOBBER.</p>
|
||
<p>>> <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 CLOBBER and APPEND_CREATE options are both
|
||
unset, this causes an error; otherwise, the file is created.</p>
|
||
<p>>>| <code>word</code><br />
|
||
>>! <code>word</code><br />
|
||
Same as >>, except that the file is created if it does not exist,
|
||
regardless of CLOBBER and APPEND_CREATE.</p>
|
||
<p><<[-] <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
|
||
‘\’, 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 <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 <<- is used, then all leading tabs are stripped from <code>word</code> and
|
||
from the document.</p>
|
||
<p><<< <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. The
|
||
result will have a trailing newline after it.</p>
|
||
<p><& <code>number</code><br />
|
||
>& <code>number</code><br />
|
||
The standard input/output is duplicated from file descriptor <code>number</code>
|
||
(see dup2(2)).</p>
|
||
<p><& -<br />
|
||
>& -<br />
|
||
Close the standard input/output.</p>
|
||
<p><& p<br />
|
||
>& p<br />
|
||
The input/output from/to the coprocess is moved to the standard
|
||
input/output.</p>
|
||
<p>>& <code>word</code><br />
|
||
&> <code>word</code><br />
|
||
(Except where ‘>& <code>word</code>’ 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 ‘> <code>word</code>’. Note
|
||
that this does <em>not</em> have the same effect as ‘> <code>word</code> 2>&1’ in the
|
||
presence of multios (see the section below).</p>
|
||
<p>>&| <code>word</code><br />
|
||
>&! <code>word</code><br />
|
||
&>| <code>word</code><br />
|
||
&>! <code>word</code><br />
|
||
Redirects both standard output and standard error (file descriptor 2) in
|
||
the manner of ‘>| <code>word</code>’.</p>
|
||
<p>>>& <code>word</code><br />
|
||
&>> <code>word</code><br />
|
||
Redirects both standard output and standard error (file descriptor 2) in
|
||
the manner of ‘>> <code>word</code>’.</p>
|
||
<p>>>&| <code>word</code><br />
|
||
>>&! <code>word</code><br />
|
||
&>>| <code>word</code><br />
|
||
&>>! <code>word</code><br />
|
||
Redirects both standard output and standard error (file descriptor 2) in
|
||
the manner of ‘>>| <code>word</code>’.</p>
|
||
<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>... 1><code>fname</code> 2>&1</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 ‘|&’ command separator described in <a href="Shell-Grammar.html#Simple-Commands-_0026-Pipelines">Simple Commands &
|
||
Pipelines</a> is a
|
||
shorthand for ‘2>&1 |’.</p>
|
||
<p>The various forms of process substitution, ‘<(<code>list</code>)’, and ‘=(<code>list</code>)’
|
||
for input and ‘>(<code>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>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
|
||
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:</p>
|
||
<blockquote>
|
||
<p>... {myfd}>&1</p>
|
||
</blockquote>
|
||
<p>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</p>
|
||
<p>The syntax {<code>varid</code>}>&-, for example {myfd}>&-, 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>param</code> or >&$<code>param</code> if <code>param</code> is
|
||
readonly.</p>
|
||
<p>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.</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
|
||
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.</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-zsh">integer myfd
|
||
exec {myfd}>~/logs/mylogfile.txt
|
||
print This is a log message. >&$myfd
|
||
exec {myfd}>&-
|
||
</code></pre>
|
||
</div>
|
||
<p>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.</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
|
||
MULTIOS option is set, as it is by default. Thus:</p>
|
||
<div class="example">
|
||
<pre><code class="language-zsh">date >foo >bar
|
||
</code></pre>
|
||
</div>
|
||
<p>writes the date to two files, named ‘foo’ and ‘bar’. Note that a pipe is
|
||
an implicit redirection; thus</p>
|
||
<div class="example">
|
||
<pre><code class="language-zsh">date >foo | cat
|
||
</code></pre>
|
||
</div>
|
||
<p>writes the date to the file ‘foo’, 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 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:</p>
|
||
<div class="example">
|
||
<pre><code class="language-zsh">date >&1 >output
|
||
</code></pre>
|
||
</div>
|
||
<p>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:</p>
|
||
<div class="example">
|
||
<pre><code class="language-zsh">date >output >&1
|
||
</code></pre>
|
||
</div>
|
||
<p>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.</p>
|
||
<p>If the MULTIOS 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-zsh">: > *
|
||
</code></pre>
|
||
</div>
|
||
<p>will truncate all files in the current directory, assuming there’s at
|
||
least one. (Without the MULTIOS option, it would create an empty file
|
||
called ‘*’.) Similarly, you can do</p>
|
||
<div class="example">
|
||
<pre><code class="language-zsh">echo exit 0 >> *.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 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.</p>
|
||
<p>Thus</p>
|
||
<div class="example">
|
||
<pre><code class="language-zsh">sort <foo <fubar
|
||
</code></pre>
|
||
</div>
|
||
<p>or even</p>
|
||
<div class="example">
|
||
<pre><code class="language-zsh">sort <f{oo,ubar}
|
||
</code></pre>
|
||
</div>
|
||
<p>is equivalent to ‘cat foo fubar | sort’.</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 >&$myfd.</p>
|
||
<p>Note that a pipe is an implicit redirection; thus</p>
|
||
<div class="example">
|
||
<pre><code class="language-zsh">cat bar | sort <foo
|
||
</code></pre>
|
||
</div>
|
||
<p>is equivalent to ‘cat bar foo | sort’ (note the order of the inputs).</p>
|
||
<p>If the MULTIOS 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-zsh">echo Hello > bar > baz
|
||
</code></pre>
|
||
</div>
|
||
<p>when MULTIOS is unset will truncate ‘bar’, and write ‘Hello’ into ‘baz’.</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-zsh">cat file >file1 >file2
|
||
cat file1 file2
|
||
</code></pre>
|
||
</div>
|
||
<p>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).</p>
|
||
<p>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:</p>
|
||
<div class="example">
|
||
<pre><code class="language-zsh">{ cat file } >file >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 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.</p>
|
||
<p><span id="index-SH_005fNULLCMD_002c-use-of"></span></p>
|
||
<p>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.</p>
|
||
<p><span id="index-READNULLCMD_002c-use-of"></span></p>
|
||
<p>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</p>
|
||
<div class="example">
|
||
<pre><code class="language-zsh">< file
|
||
</code></pre>
|
||
</div>
|
||
<p>shows the contents of file on standard output, with paging if that is a
|
||
terminal. NULLCMD and READNULLCMD may refer to shell functions.</p>
|
||
<hr />
|
||
<p>This document was generated on <em>May 14, 2022</em> using <a href="http://www.nongnu.org/texi2html/"><em>texi2html
|
||
5.0</em></a>.<br />
|
||
Zsh version 5.9, released on May 14, 2022.</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">
|
||
const wsProtocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
|
||
const wsAddress = wsProtocol + "//" + location.host + "/" + "__livereload";
|
||
const socket = new WebSocket(wsAddress);
|
||
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>
|