= Redirection
:encoding: UTF-8
:lang: en
//:title: Yash manual - Redirection
:description: This page describes redirections supported by yash.

dfn:[Redirection] is a feature you can use to modify file descriptors of
commands.
By using redirection, you can execute commands with their standard
input/output connected with files or devices other than the terminal.

You can do redirection by adding redirection operators to a command
(link:syntax.html#simple[simple command] or
link:syntax.html#compound[compound command])
In a simple command, redirection operators may appear anywhere in the command
as long as operator tokens are separated from other tokens.
In a compound command, redirection operators must appear at the end of the
command.

Redirection operators are processed before the command body is executed. More
than one redirection operator in a command are processed in the order of
appearance.
Redirection operators affect only the command in which they appear,
except when they appear in an link:_exec.html[exec built-in]
without command operands.
That is, file descriptors modified by redirection are restored after the
command has finished.

A redirection operator starts with +<+ or +>+.
Redirection operators starting with +<+ affects the standard input (file
descriptor 0) by default.
Redirection operators starting with +>+ affects the standard output (file
descriptor 1) by default.
To affect another file descriptor, you can prefix a redirection operator with
a non-negative integer; the operator will affect the file descriptor specified
by the integer.
The integer must immediately precede the +<+ or +>+ without any whitespaces
in between. The integer must not be link:syntax.html#quotes[quoted], either.

Words of the form +&#x7B;{{name}}&#x7D;+ that immediately precede a
redirection operator are reserved for future use.
Currently, they cause a syntax error if used.

[[file]]
== Redirection to files

The most common type of redirection is redirection to files.

Redirection of input::
+&lt; {{token}}+

Redirection of output::
+&gt; {{token}}+
+
+&gt;| {{token}}+
+
+&gt;&gt; {{token}}+

Redirection of input and output::
+&lt;&gt; {{token}}+

The {{token}} is subject to the link:expand.html[four expansions].
It is also subject to link:expand.html#glob[pathname expansion]
if the shell is link:interact.html[interactive].
The expansion result is treated as the pathname of the file to which
redirection is performed.
If the pathname expansion does not result in a single pathname,
it is an error.

In redirection of input, the standard input is replaced with a file descriptor
which is open for read-only access to the target file.
If the target file cannot be opened for read-only access, it is an error.

In redirection of output, the standard output is replaced with a file
descriptor which is open for write-only access to the target file.
If the target file cannot be opened for write-only access, it is an error.
If the target file does not exist, a new empty file is created and opened.
If the target file already exists, the file is opened as follows:

- For the +&gt;|+ operator, the file is emptied when opened if it is a regular
  file.
- For the +&gt;+ operator, the behavior is the same as the +&gt;|+ operator
  if the link:_set.html#so-clobber[clobber option] is enabled.
  If the option is disabled and the file is a regular file, it is treated as
  an error.
- For the +&gt;&gt;+ operator, the file is opened for appending;
  any output to the file descriptor is appended to the end of the file.

In redirection of input and output, the standard input is replaced with a file
descriptor which is open for read-and-write access to the target file.
If the file does not exist, a new empty file is created and opened.

[[socket]]
=== Socket redirection

If the pathname of the target file is of the form
+/dev/tcp/{{host}}/{{port}}+ or +/dev/udp/{{host}}/{{port}}+ and
the file cannot be opened in the usual manner,
a new socket is opened for communication with the {{port}} of the {{host}}.
The redirection replaces the standard input or output with the file descriptor
to the socket.

A stream socket is opened for the form +/dev/tcp/{{host}}/{{port}}+ and
a datagram socket for the form +/dev/udp/{{host}}/{{port}}+.
The protocol actually used for communication is determined by the socket
library the shell uses.
Typically, stream sockets use TCP and datagram sockets UDP.

In socket redirection, the file descriptor is both readable and writable
regardless of the type of the redirection operator used.

Socket redirection is yash's extension that is not defined in POSIX.
Bash as well has socket redirection as extension.

[[dup]]
== Duplication of file descriptors

Redirection allows duplicating or closing existing file descriptors.

Duplication of file descriptor::
+&lt;&amp; {{token}}+
+
+&gt;&amp; {{token}}+

The {{token}} is subject to expansion as in <<file,redirection to files>>,
but it is treated as a file descriptor rather than a pathname.
Thus the expanded {{token}} must be a non-negative integer.

The +&lt;&amp;+ and +&gt;&amp;+ operators duplicate the file descriptor
specified by {{token}} to the standard input and output, respectively.
(The operators can be prefixed with a non-negative integer so that the file
descriptor is duplicated to a file descriptor other than the standard input or
output.)

If the expanded {{token}} is a single hyphen rather than a non-negative
integer, the file descriptor is closed rather than duplicated.
By default, the +&lt;&amp;+ and +&gt;&amp;+ operators close the standard input
and output, respectively, but the operators can be prefixed with a
non-negative integer so that another file descriptor is closed.

In the link:posix.html[POSIXly-correct mode], a file descriptor must be
readable when duplicated by the +&lt;&amp;+ operator and writable when
duplicated by the +&gt;&amp;+ operator.

[[here]]
== Here documents and here strings

dfn:[Here document] and dfn:[here string] allow redirection to file
descriptors that reads strings directly specified in shell commands.

Here document::
+&lt;&lt; {{token}}+
+
+&lt;&lt;- {{token}}+

Here string::
+&lt;&lt;&lt; {{token}}+

In a here document or here string, the standard input is replaced with a
readable file descriptor.
When the command reads from the file descriptor, it will read the contents of
the here document/string, which is defined below.

When a here document operator (+&lt;&lt;+ or +&lt;&lt;-+) appears in a
command, the shell reads the contents of the here document starting from the
next line.
The contents of here documents are not parsed nor executed as commands.
The {{token}} after the operand specifies a delimiter that indicates the end
of the contents.
(The {{token}} is not subject to any link:expand.html[expansion], but
link:syntax.html#quotes[quotation] is processed.)
The contents of the here document is terminated just before the first line
containing the {{token}} only.
When using the +&lt;&lt;-+ operator, all tab characters at the beginning of
each line in the here document contents are removed and the delimiter
{{token}} may be preceded by tab characters.

If there are more than one here document operator on one line,
the contents of the here documents are parsed in order:
The contents of the first here document starts from the next line and ends
before the first line containing the {{token}} that followed the first
operator.
Just after that line, the contents of the second here document starts, and so
on.

The contents of here documents are treated literally:
whitespaces, tabs, etc. remain as is.
The exception is that, when the {{token}} is not
link:syntax.html#quotes[quoted] at all:

- the contents are subject to
  link:expand.html#params[parameter expansion],
  link:expand.html#cmdsub[command substitution],
  link:expand.html#arith[arithmetic expansion].
- a backslash in the contents is treated as link:syntax.html#quotes[quotation]
  if and only if it precedes +$+, +`+, +"+, or another backslash.
- a backslash followed by a newline is treated as
  link:syntax.html#quotes[line continuation].

In here string, the {{token}} after the operator is subject to expansion
as in <<file,redirection to files>>.
The expansion result becomes the contents of the here string.
A newline character is automatically appended to the end of here string
contents.

Here string is yash's extension that is not defined in POSIX.
Other shells like bash, ksh, and zsh have the same feature.

[[pipe]]
== Pipeline redirection

dfn:[Pipeline redirection] allows opening pipelines that can be used for
arbitrary purposes.

Pipeline redirection::
+&gt;&gt;| {{token}}+

The {{token}} is subject to expansion as in <<file,redirection to files>>,
but it is treated as a file descriptor rather than a pathname.
Thus the expanded {{token}} must be a non-negative integer.

Pipeline redirection opens a new pipeline.
The standard output (or the file descriptor specified before the operator, if
any) is replaced with the file descriptor open for writing to the pipeline.
The file descriptor specified by {{token}} is replaced with the file
descriptor open for reading from the pipeline.

Pipeline redirection is yash's extension that is not defined in POSIX.

[[process]]
== Process redirection

dfn:[Process redirection] creates a pipeline connected to another command.

Process redirection::
+&lt;({{command}}...)+
+
+&gt;({{command}}...)+

In process redirection, the {{command}} specified is executed in a
link:exec.html#subshell[subshell].
If the process redirection is of the form +&lt;({{command}}...)+, the standard
output of {{command}} is connected with a pipeline to the standard input of
the command the redirection is associated with.
If the process redirection is of the form +&gt;({{command}}...)+, the standard
input of {{command}} is connected with a pipeline to the standard output of
the command the redirection is associated with.

Process redirection is yash's extension that is not defined in POSIX.
Bash and zsh have a feature called process substitution, which uses the same
syntax as yash's process redirection, but incompatibly differs in behavior.

// vim: set filetype=asciidoc textwidth=78 expandtab:
