What's the difference of redirect an output using , & , & and 2& ?
>
redirects stdout to a file2>&
redirects file handle "2" (almost always stderr) to some other file handle (it's generally written as2>&1
, which redirects stderr to the same place as stdout).&>
and>&
redirect both stdout and stderr to a file. It's normally written as&>file
(or>&file
). It's functionally the same as>file 2>&1
.2>
redirects output to file handle 2 (usually stderr) to a file.
What does 2 &1 mean?
File descriptor 1 is the standard output (stdout
).
File descriptor 2 is the standard error (stderr
).
At first, 2>1
may look like a good way to redirect stderr
to stdout
. However, it will actually be interpreted as "redirect stderr
to a file named 1
".
&
indicates that what follows and precedes is a file descriptor, and not a filename. Thus, we use 2>&1
. Consider >&
to be a redirect merger operator.
What's difference between 2 1 /dev/null and 2 &1 /dev/null ?
The &
means file descriptor1. So 2>&1
redirects standard error to whatever standard output currently points at, while 2>1
redirects standard error into a file called 1
.
Also, the redirects happen in order. So if you say 2>&1 >/dev/null
, it redirects standard error to point at what standard output currently points at (which is probably a noop), then redirects stdout to /dev/null. You probably want >/dev/null 2>&1
.
1In the context of a file redirect -- when it is the next token immediately after a >
or <
. In other contexts it means something else.
What's the difference between & foo and foo 2 &1 ?
From the bash manual:
There are two formats for redirecting standard output and standard error:
&>word
and
>&word
Of the two forms, the first is preferred. This is semantically equivalent to
>word 2>&1
The phrase "semantically equivalent" should settle the issue with your coworker.
linux redirection: difference between using 2 &1 before and after somfilename
Not sure about zsh but according to Bash manual:
Note that the order of redirections is significant. For example, the
command
ls > dirlist 2>&1
directs both standard output and standard error to the file dirlist,
while the command
ls 2>&1 > dirlist
directs only the standard output to file dirlist, because the standard
error was duplicated as standard output before the standard output was
redirected to dirlist.
For ls > dirlist 2>&1
, this is what happens (in pseudo C code):
fd = open("dirlist");
dup2(fd, 1); // now stdout is a dup of fd so stdout points to "dirlist"
dup2(1, 2); // now stderr becomes a dup of stdout so it also points to "dirlist"
For ls 2>&1 > dirlist
, this is what happens:
// initially, both stdout and stderr point to the tty
dup2(1, 2); // now stderr becomes a dup of stdout so they still point to the tty
fd = open("dirlist");
dup2(fd, 1); // now stdout is a dup of fd so stdout points to "dirlist",
// but stderr still points to tty
linux redirection: difference between using 2 &1 before and after somfilename
Not sure about zsh but according to Bash manual:
Note that the order of redirections is significant. For example, the
command
ls > dirlist 2>&1
directs both standard output and standard error to the file dirlist,
while the command
ls 2>&1 > dirlist
directs only the standard output to file dirlist, because the standard
error was duplicated as standard output before the standard output was
redirected to dirlist.
For ls > dirlist 2>&1
, this is what happens (in pseudo C code):
fd = open("dirlist");
dup2(fd, 1); // now stdout is a dup of fd so stdout points to "dirlist"
dup2(1, 2); // now stderr becomes a dup of stdout so it also points to "dirlist"
For ls 2>&1 > dirlist
, this is what happens:
// initially, both stdout and stderr point to the tty
dup2(1, 2); // now stderr becomes a dup of stdout so they still point to the tty
fd = open("dirlist");
dup2(fd, 1); // now stdout is a dup of fd so stdout points to "dirlist",
// but stderr still points to tty
Difference between '2 &1' and '& filename'
cat file1 file2
It will give an error like this
hello cat: file2: No such file or directory
The error is simply telling you file2
does not exist. You create file1
with your redirection:
echo hello > file1
Now file1
exists. When you do cat file1 file2
, cat
attempts to output the contents of file1
& file2
to stdout
, but file2
doesn't exist (it tells you). To make file2
, you can do cat file1 > file2
to redirect the output of cat file1
to file2
, or you can simply cp file1 file2
. Then file2
will exist.
I want to redirect the STDOUT and STDERR, so
cat file1 file2 > file3 2>&1 | cat
hello
cat: file2: No such file or directory
Again, file2
still doesn't exist. cat
short for concatenate
simply output the contents of the files given as input to stdout
unless redirected. file1
contains hello
so it is output along with the error. hello
is redirected to file3
, ...and..., since you have redirected stderr
to stdout
(e.g. 2>&1
), the error message also ends up in file3
The |
(pipe) command in Linux shell just takes the stdout
from the command on the left and redirects it to the stdin
of the command after the pipe. Since you already redirected the stdout
and stderr
from cat file1 file2
into file3
, nothing is sent to the cat
following the pipe. The output you posted appears to have come from:
cat file3
In a Linux shell, stdin, stdout and stderr
are simply special files that represent file descriptors 0, 1 & 2
, respectively. The actual files in the filesystem are /dev/stdin
, /dev/stdout
, and /dev/stderr
. If you check with the ls -l
command, you will see the relation between the file and file descriptors:
$ ls -l /dev/std*
lrwxrwxrwx 1 root root 4 Apr 2 17:47 /dev/stderr -> fd/2
lrwxrwxrwx 1 root root 4 Apr 2 17:47 /dev/stdin -> fd/0
lrwxrwxrwx 1 root root 4 Apr 2 17:47 /dev/stdout -> fd/1
How to redirect and append both standard output and standard error to a file with Bash
cmd >>file.txt 2>&1
Bash executes the redirects from left to right as follows:
>>file.txt
: Openfile.txt
in append mode and redirectstdout
there.2>&1
: Redirectstderr
to "wherestdout
is currently going". In this case, that is a file opened in append mode. In other words, the&1
reuses the file descriptor whichstdout
currently uses.
Related Topics
How to Wrap Lines Within Columns in Linux
Is Kernel Space Mapped into User Space on Linux X86
Why Didn't I Get Segmentation Fault When Storing Past the End of the Bss
Explicitly Invoke Sig_Dfl/Sig_Ign Handlers on Linux
Deleting String Up to the First Occurrence of Certain Character
Command Substitution Within Sed Expression
How to Tell Qt to Use Different Openssl
Sed Returns "Sed: Command Garbled"
How to Parse Command Line Options in Bash Shell
Why Do My Results Different Following Along the Tiny Asm Example
Shell Script for Multithreading a Process
Emulating Slurm on Ubuntu 16.04
How to Not Transfer Changes Done to Files from a Branch to a Another in Git
Sed Command Working on Command Line But Not in Perl Script
Bash Foreach Loop Works Differently When Executed from .Sh File
How to Determine Ssl Cert Expiration Date from a Pem Encoded Certificate