shI/O redirection short reference
The [n] is an optional number, as in ‘3’ (not ‘’), that refers to a file descriptor. [n]> file Redirect standard output (or n) to file. [n]>> file Append standard output (or n) to file. [n]< file Redirect standard input (or n) from file. [n1]<&n2 Duplicate n2 to standard input (or n1). [n]<&- Close standard input (or n). [n1]>&n2 Duplicate n2 to standard output (or n1). [n]>&- Close standard output (or n).
bash has all of these operators and more.
File descriptors 3 through 9 are empty by default, but 5 can cause some trouble. These empty file descriptors may be used to temporarily copy one of the default file descriptors. One use of a copy is to redirect standard output to a file temporarily and then back to the terminal (example).
make 2>&1 | grep Erroror
make 2<&1 | grep Error
Why do both of these work? Look at some more examples.
bash both provide at least two syntaxes for manipulating file descriptors.
one, two, threeinto the file
echo "one, two, three" 1> numbers.txt
In this inline form of redirection, standard output for the
echo command is redirected into
exec 1> numbers.txt echo "one, two, three"
exec redirection diverts standard output to
numbers.txt for any command that follows it.
exec example hints at the fact that
Child processes inherit open file descriptors (TLDP). To further explore this concept let's try the redirection again, but
accidentally leave out
1> numbers.txt echo "one, two, three"This just creates an empty
numbers.txtfile and then echoes
one, two, threeto the terminal. The problem is that the shell spawns one child process to run the redirection, lets that process end, and then creates a new sibling child process for the
echo. To run multiple commands that all inherit the redirection, we need to put the
execback where it was.
exec 1> numbers.txt echo "one, two, three"With the
execback in place, the shell still spawns a new process and redirects
numbers.txt, but now the
execcauses the new process to become the parent process for any subsequent commands. Therefore
echoruns as a child process of the redirection,
inherits the open file descriptors,and sends
one, two, threeto
numbers.txtrather than the terminal.
Redirecting output first to a file and then back to the terminal can be done using either inline or
echo "one, two, three" 1> numbers.txt echo "Numbers written."In the first
stdoutis redirected to
numbers.txt, but then that process ends. The process for the second
echohas no redirections, and therefore outputs to the terminal.
exec 9>&1 1> numbers.txt echo "one, two, three" exec 1>&9 9>&- echo "Numbers written."
Extra care must be taken when redirecting with
exec due to
exec's reparenting effects. One way to restore
stdout to the terminal is to save the
pointer to the terminal in an unused file descriptor (fd 9 in this case) before redirecting
stdout. This saved copy is carried through the process (and child processes) until it is copied back to
stdout (fd 1).
This example also demonstrates that multiple redirects can be made using a single
exec 1> numbers.txt echo "one, two, three" exec 1> "$(tty)" echo "Numbers written."
Another way to re-redirect
stdout to the terminal is to use the filename that represents the terminal (via the
tty command in this case).
A more common way to write this would be…echo "one, two, three" 1> numbers.txt
Theecho "one, two, three" > numbers.txt
1may be omitted because
>redirects fd 1 by default.
…but the more common form would be…cat 0< numbers.txt
…where file descriptorcat < numbers.txt
execis particularly helpful.
shredirection is to implement it again using C library calls. Maybe do something like: open a pipe,
forka child process, duplicate (
dup2) file descriptors as needed and
closeunused file descriptors, execute (
execv) a program in the child process,
writebytes through the pipe to the child process from the parent process, and
closeany remaining unneeded file descriptors.
|2013 Jan 08||Comments link and errors to stdout example|
|2012 Aug 15||some rewordings|
|2011 Sep 11||markup corrections|
|2011 Apr 28||link to GNU libc manual. reword the dash man page excerpt.|
|2011 Jan 25||another way to get back to the terminal: the terminal's /dev filename|
|2010 Dec 15||posted|