Advanced I/O
Unix I/O is performed by assigning file descriptors to files or devices, and then
using those descriptors for reading and writing. Descriptors 0, 1, and 2 are always
used for stdin, stdout and stderr respectively. Stdin defaults to the keyboard,
while stdout and stderr both default to the current terminal window.
Redirecting for the whole script
Redirecting stdout, stderr and other file descriptors for the whole script
can be done with the exec
command.
exec
> outfile < infile
- with no command, the
exec
just reassigns the I/O of the current shell.
exec n>outfile
- The form n<, n> opens file descriptor n instead of the default stdin/stdout.
This can then be used with
read -u
or print -u
.
Explicitly opening or duplicating file descriptors
One reason to do this is to save the current
state of stdin/stdout, temporarily reassign them, then restore them.
>&n
- standard output is moved to whatever file descriptor n is currently pointing to
<&n
- standard input is moved to whatever file descriptor n is currently pointing to
n>file
- file descriptor n is opened for writing on the named file.
n>&1
- file descriptor n is set to whatever file descriptor 1 is currently pointing to.
Example Sending messages to stderr (2) instead of stdout (1)
echo "Error: program failed" >&2
Echo always writes to stdout, but stdout can be temporarily reassigned to duplicate stderr (or other file
descriptors).
Conventionally Unix programs send error messages to stderr to keep them separated from stdout.
Input and output to open file descriptors (ksh)
Printing to file descriptors (usually more efficient than open/append/close):
print
-u n args
- print to file descriptor n.
- -p
- write to the pipe to a coprocess (opened by |&)
Reading from file descriptors other than stdin:
read
-u n var1 var2 rest
- read a line from file descriptor n, parsing by $IFS, and placing the words into
the named variables. Any left over words all go into the last variable.
- -p
- read from the pipe to a coprocess (opened by |&)
Closing file handles
<&-
- standard input is explicitly closed
>&-
- standard output is explicitly closed
For example, to indicate to another program downstream in a pipeline that no more
data will be coming. All file descriptors are closed when a script exits.
I/O redirection operators are evaluated left-to-right. This makes a difference in a
statement like:
">filename 2>&1
". (Many books with example scripts get this wrong)
"Here" documents
<< [-]string
- redirect input to the temporary file formed by everything up the matching string
at the start of a line. Allows for placing file content inline in a script.
Example: ex5 display, text
Example: duplex display, text