====== Redirection ======
Fix me: To be continued
\\
Redirection makes it possible to control where the output of a command goes to, and where the input of a command comes from. It's a mighty tool that, together with pipelines, makes the shell powerful. The redirection operators are checked whenever a [[syntax:grammar:parser_exec | simple command is about to be executed]].
Under normal circumstances, there are 3 files open, accessible by the file descriptors 0, 1 and 2, all connected to your terminal:
^Name^FD^Description^
|''stdin''|0|standard input stream (e.g. keyboard)|
|''stdout''|1|standard output stream (e.g. monitor)|
|''stderr''|2|standard error output stream (usually also on monitor)|
The terms "monitor" and "keyboard" refer to the same device, the **terminal** here. Check your preferred UNIX(r)-FAQ for details, I'm too lazy to explain what a terminal is ;-)
Both, ''stdout'' and ''stderr'' are output file descriptors. Their difference is the **convention** that a program outputs payload on ''stdout'' and diagnostic- and error-messages on ''stderr''. If you write a script that outputs error messages, please make sure you follow this convention!
Whenever you **name** such a filedescriptor, i.e. you want to redirect this descriptor, you just use the number:
# this executes the cat-command and redirects its error messages (stderr) to the bit bucket
cat some_file.txt 2>/dev/null
Whenever you **reference** a descriptor, to point to its current target file, then you use a "''&''" followed by a the descriptor number:
# this executes the echo-command and redirects its normal output (stdout) to the standard error target
echo "There was an error" 1>&2
The redirection operation can be **anywhere** in a simple command, so these examples are equivalent:
cat foo.txt bar.txt >new.txt
cat >new.txt foo.txt bar.txt
>new.txt cat foo.txt bar.txt
Every redirection operator takes one or two words as operands. If you have to use operands (e.g. filenames to redirect to) that contain spaces you **must** quote them!
===== Valid redirection targets and sources =====
This syntax is recognized whenever a ''TARGET'' or a ''SOURCE'' specification (like below in the details descriptions) is used.
^Syntax^Description^
|''FILENAME''|references a normal, ordinary filename from the filesystem (which can of course be a FIFO, too. Simply everything you can reference in the filesystem)|
|''&N''|references the current target/source of the filedescriptor ''N'' ("duplicates" the filedescriptor)|
|''&-''|closes the redirected filedescriptor, useful instead of ''> /dev/null'' constructs (''> &-'')|
|''/dev/fd/N''|duplicates the filedescriptor ''N'', if ''N'' is a valid integer|
|''/dev/stdin''|duplicates filedescriptor 0 (''stdin'')|
|''/dev/stdout''|duplicates filedescriptor 1 (''stdout'')|
|''/dev/stderr''|duplicates filedescriptor 2 (''stderr'')|
|''/dev/tcp/HOST/PORT''|assuming ''HOST'' is a valid hostname or IP address, and ''PORT'' is a valid port number or service name: redirect from/to the corresponding TCP socket|
|''/dev/udp/HOST/PORT''|assuming ''HOST'' is a valid hostname or IP address, and ''PORT'' is a valid port number or service name: redirect from/to the corresponding UDP socket|
If a target/source specification fails to open, the whole redirection operation fails. Avoid referencing file descriptors above 9, since you may collide with file descriptors Bash uses internally.
===== Redirecting output =====
N > TARGET
This redirects the file descriptor number ''N'' to the target ''TARGET''. If ''N'' is omitted, ''stdout'' is assumed (FD 1). The ''TARGET'' is **truncated** before writing starts.
If the option ''noclobber'' is set with [[commands:builtin:set | the set builtin]], with cause the redirection to fail, when ''TARGET'' names a regular file that already exists. You can manually override that behaviour by forcing overwrite with the redirection operator ''>|'' instead of ''>''.
===== Appending redirected output =====
N >> TARGET
This redirects the file descriptor number ''N'' to the target ''TARGET''. If ''N'' is omitted, ''stdout'' is assumed (FD 1). The ''TARGET'' is **not truncated** before writing starts.
===== Redirecting output and error output =====
&> TARGET
>& TARGET
This special syntax redirects both, ''stdout'' and ''stderr'' to the specified target. It's **equivalent** to
> TARGET 2>&1
Since Bash4, there's ''&>>TARGET'', which is equivalent to ''>> TARGET 2>&1''.
This syntax is deprecated and should not be used. See the page about [[scripting:obsolete | obsolete and deprecated syntax]].
===== Appending redirected output and error output =====
To append the cumulative redirection of ''stdout'' and ''stderr'' to a file you simply do
>> FILE 2>&1
&>> FILE
===== Transporting stdout and stderr through a pipe =====
COMMAND1 2>&1 | COMMAND2
COMMAND1 |& COMMAND2
===== Redirecting input =====
N < SOURCE
The input descriptor ''N'' uses ''SOURCE'' as its data source. If ''N'' is omitted, filedescriptor 0 (''stdin'') is assumed.
===== Here documents =====
<
<<-TAG
...
TAG
A here-document is an input redirection using source data specified directly at the command line (or in the script), no "external" source. The redirection-operator ''<<'' is used together with a tag ''TAG'' that's used to mark the end of input later:
# display help
cat <
As you see, substitutions are possible. To be precise, the following substitutions and expansions are performed in the here-document data:
* [[syntax:pe | Parameter expansion]]
* [[syntax:expansion:cmdsubst | Command substitution]]
* [[syntax:expansion:arith | Arithmetic expansion]]
You can avoid that by quoting the tag:
cat <<"EOF"
This won't be expanded: $PATH
EOF
Last but not least, if the redirection operator ''<<'' is followed by a ''-'' (dash), all **leading TAB** from the document data will be ignored. This might be useful to have optical nice code also when using here-documents.
The tag you use **must** be the only word in the line, to be recognized as end-of-here-document marker.
It seems that here-documents (tested on versions ''1.14.7'', ''2.05b'' and ''3.1.17'') are correctly terminated when there is an EOF before the end-of-here-document tag. The reason is unknown, but it seems to be done on purpose. Bash 4 introduced a warning message when end-of-file is seen before the tag is reached.
===== Here strings =====
<<< WORD
The here-strings are a variation of the here-documents. The word ''WORD'' is taken for the input redirection:
cat <<< "Hello world... $NAME is here..."
Just beware to quote the ''WORD'' if it contains spaces. Otherwise the rest will be given as normal parameters.
The here-string will append a newline (''\n'') to the data.
===== Multiple redirections =====
More redirection operations can occur in a line of course. The order is **important**! They're evaluated from **left to right**.
If you want to redirect both, ''stderr'' and ''stdout'' to the same file (like ''/dev/null'', to hide it), this is **the wrong way**:
# { echo OUTPUT; echo ERRORS >&2; } is to simulate something that outputs to STDOUT and STDERR
# you can test with it
{ echo OUTPUT; echo ERRORS >&2; } 2>&1 1>/dev/null
Why? Relatively easy:
* initially, ''stdout'' points to your terminal (you read it)
* same applies to ''stderr'', it's connected to your terminal
* ''2>&1'' redirects ''stderr'' away from the terminal to the target for ''stdout'': **the terminal** (again...)
* ''1>/dev/null'' redirects ''stdout'' away from your terminal to the file ''/dev/null''
What remains? ''stdout'' goes to ''/dev/null'', ''stderr'' still (or better: "again") goes to the terminal. You have to swap the order to make it do what you want:
{ echo OUTPUT; echo ERRORS >&2; } 1>/dev/null 2>&1
===== Examples =====
How to make a program quiet (assuming all output goes to ''STDOUT'' and ''STDERR''?
command >/dev/null 2>&1
===== See also =====
* Internal: [[howto:redirection_tutorial | Illustrated Redirection Tutorial]]
* Internal: [[commands:builtin:set#tag_noclobber | The noclobber option]]
* Internal: [[commands:builtin:exec | The exec builtin command]]
* Internal: [[syntax:grammar:parser_exec | Simple commands parsing and execution]]
* Internal: [[syntax:expansion:proc_subst | Process substitution syntax]]
* Internal: [[scripting:obsolete | Obsolete and deprecated syntax]]