I'm trying to understand output redirection, but I'm struggeling. I don't think I really get the differences.
1 > file # - redirect stdout to file (override mode)
1 >> file # - redirect stdout to file (append mode)
2 > 1 # 1) would that also redirect stderr to stdout, replacing stdout?
2 >> 1 # 2) would this redirect stderr to stdout (appending to it,
# i.e. haivng both sent to stdout?)
1>&9 # - duplicates stdout to file descriptor (pointer) 9
# 3) what's the difference of 2>&1 to a 2 >> 1? Does >> only run at the end
# of output?
echo foo > file # - redirects output to file (override mode)
>file 2>&1 # - duplicates stderr to stdout, then redirects to file in override mode
# 4) why is this giving me stdout, too, when the syntax is 2>&1,
# i.e. duplicate stderr into stdout - not merge 2 into 1?
I'm assuming the ampersand &
means duplicate, as opposed to redirect. But what's the difference of redirecting a
to b
(will a
remain unchanged?) to duplicating a
to b
(will a
and b
be the same?)? 2>&1
effectively seems to redirect and merge 2
into 1
, i.e. what would have gone into 2
is now in 1
, but only in 1
… why?
I'm so confused…
Best Answer
First, anything after
>
or>>
is a file name; so> 1
writes to a file named1
.Numbers in the other forms given in your example are file descriptors. By default, programs start with file descriptors 0 (standard input), 1 (standard output) and 2 (standard error) connected; when you start a program from an interactive shell, these are connected to the terminal's input and output (you can see these by running
ls -l /proc/$$/fd
on Linux).Specifying a number before
>
,>>
or>&
specifies the file descriptor you wish to manipulate; the number has to be right in front of the>
symbol. Thuswill print "Example" and create an empty
stderr
file (which would contain anything sent to the standard error).You can think of file descriptors as entries in a table, pointing to files; thus by default:
/dev/tty
/dev/tty
/dev/tty
Specifying
1> file
(or simply> file
) updates file descriptor 1 to point tofile
, opened in truncating mode (so its contents are replaced). Specifying2> 1
updates file descriptor 2 to point to a file named1
, opened in truncating mode.Duplicating file descriptors using
>&
(or&>
, which is the preferred form) simply updates one file descriptor to point to whatever the other is pointing at. In your last example,> file
updates file descriptor 1:/dev/tty
file
/dev/tty
and then
2>&1
updates file descriptor 2:/dev/tty
file
file
(order is significant:
> file 2>&1
produces the above,2>&1 > file
would only end up redirecting file descriptor 1).The
1>&9
form only works if file descriptor 9 has been opened, e.g. by copying file descriptor 1 to it (9>&1
) or by opening a file (9> file
). This type of construct can be useful to keep track of the original contents of file descriptors when redirecting; thus in a script you could copy 1 and 2 safely away, redirect standard output and error for whatever purpose you need, and then restore them...The Bash manual has all the details.