2023-07-05 11:43:35 +02:00
# Redirection
2024-10-08 06:00:17 +02:00
!!! warning "FIXME"
To be continued
2023-07-05 11:43:35 +02:00
Redirection makes it possible to control where the output of a command
2024-03-30 19:22:45 +01:00
goes to, and where the input of a command comes from. It's a mighty
2023-07-05 11:43:35 +02:00
tool that, together with pipelines, makes the shell powerful. The
redirection operators are checked whenever a [simple command is about to
2024-01-29 02:01:50 +01:00
be executed](../syntax/grammar/parser_exec.md).
2023-07-05 11:43:35 +02:00
Under normal circumstances, there are 3 files open, accessible by the
file descriptors 0, 1 and 2, all connected to your terminal:
2024-10-08 06:00:17 +02:00
|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)|
2023-07-05 11:43:35 +02:00
2024-10-08 06:00:17 +02:00
!!! info "INFO"
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 ;-)
2023-07-05 11:43:35 +02:00
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
2024-10-08 06:00:17 +02:00
file, then you use a "`& `" followed by a the descriptor number:
2023-07-05 11:43:35 +02:00
# 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
2024-10-08 06:00:17 +02:00
!!! info "important"
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!
2023-07-05 11:43:35 +02:00
## Valid redirection targets and sources
This syntax is recognized whenever a `TARGET` or a `SOURCE`
specification (like below in the details descriptions) is used.
2024-10-08 06:00:17 +02:00
|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|
2023-07-05 11:43:35 +02:00
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 [the set
2024-01-29 02:01:50 +01:00
builtin](../commands/builtin/set.md), with cause the redirection to fail,
2023-07-05 11:43:35 +02:00
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
2024-03-30 19:22:45 +01:00
specified target. It's **equivalent** to
2023-07-05 11:43:35 +02:00
> TARGET 2>&1
2024-03-30 19:22:45 +01:00
Since Bash4, there's `&>>TARGET` , which is equivalent to
2023-07-05 11:43:35 +02:00
`>> TARGET 2>&1` .
2024-10-08 06:00:17 +02:00
!!! info "important"
This syntax is deprecated and should not be
used. See the page about [obsolete and deprecated
syntax](../scripting/obsolete.md).
2023-07-05 11:43:35 +02:00
## 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
2024-04-01 06:10:32 +02:00
< BOOKMARK:tag_heredoc >
2023-07-05 11:43:35 +02:00
< < TAG
...
TAG
< < -TAG
...
TAG
A here-document is an input redirection using source data specified
2024-10-08 06:00:17 +02:00
directly at the command line (or in the script), no "external" source.
2024-03-30 19:22:45 +01:00
The redirection-operator `<<` is used together with a tag `TAG` that's
2023-07-05 11:43:35 +02:00
used to mark the end of input later:
# display help
cat < < EOF
Sorry...
No help available yet for $PROGRAM.
Hehe...
EOF
As you see, substitutions are possible. To be precise, the following
substitutions and expansions are performed in the here-document data:
2024-01-29 02:01:50 +01:00
- [Parameter expansion ](../syntax/pe.md )
- [Command substitution ](../syntax/expansion/cmdsubst.md )
- [Arithmetic expansion ](../syntax/expansion/arith.md )
2023-07-05 11:43:35 +02:00
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.
2024-10-08 06:00:17 +02:00
!!! info "info"
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.
2023-07-05 11:43:35 +02:00
## 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
2024-10-08 06:00:17 +02:00
**important**! They're evaluated from **left to right** . If you want to
2023-07-05 11:43:35 +02:00
redirect both, `stderr` and `stdout` to the same file (like `/dev/null` ,
to hide it), this is **the wrong way** :
``` bash
# { 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)
2024-03-30 19:22:45 +01:00
- same applies to `stderr` , it's connected to your terminal
2023-07-05 11:43:35 +02:00
- `2>&1` redirects `stderr` away from the terminal to the target for
2024-10-08 06:00:17 +02:00
`stdout` : **the terminal** (again...)
2023-07-05 11:43:35 +02:00
- `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:
2024-10-08 06:00:17 +02:00
"again") goes to the terminal. You have to swap the order to make it
2023-07-05 11:43:35 +02:00
do what you want:
``` bash
{ 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: [Illustrated Redirection
2024-01-29 02:01:50 +01:00
Tutorial](../howto/redirection_tutorial.md)
2023-07-05 11:43:35 +02:00
- Internal: [The noclobber
2024-01-29 02:01:50 +01:00
option](../commands/builtin/set.md#tag_noclobber)
- Internal: [The exec builtin command ](../commands/builtin/exec.md )
2023-07-05 11:43:35 +02:00
- Internal: [Simple commands parsing and
2024-01-29 02:01:50 +01:00
execution](../syntax/grammar/parser_exec.md)
2023-07-05 11:43:35 +02:00
- Internal: [Process substitution
2024-01-29 02:01:50 +01:00
syntax](../syntax/expansion/proc_subst.md)
- Internal: [Obsolete and deprecated syntax ](../scripting/obsolete.md )
2023-07-05 11:43:35 +02:00
- Internal: [Nonportable syntax and command
2024-01-29 02:01:50 +01:00
uses](../scripting/nonportable.md)