Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

exec n<&m versus exec n>&m -- based on Sobell's Linux book

In Mark Sobell's A Practical Guide to Linux Commands, Editors, and Shell Programming, Second Edition he writes (p. 432):

The <& token duplicates an input file descriptor; >& duplicates an output file descriptor.

This seems to be inconsistent with another statement on the same page:

Use the following format to open or redirect file descriptor n as a duplicate of file descriptor m:

exec n<&m

and with an example also on the same page:

# File descriptor 3 duplicates standard input
# File descriptor 4 duplicates standard output
exec 3<&0 4<&1

If >& duplicates an output file descriptor then should we not say

exec 4>&1

to duplicate standard output?

like image 298
Alexandros Gezerlis Avatar asked May 04 '11 04:05

Alexandros Gezerlis


1 Answers

The example is right in practice. The book's original explanation is an accurate description of what the POSIX standard says, but the POSIX-like shells I have handy (bash and dash, the only ones I believe are commonly seen on Linux) are not that picky.

The POSIX standard says the same thing as the book about input and output descriptors, and goes on to say this: for n<&word, "if the digits in word do not represent a file descriptor already open for input, a redirection error shall result". So if you want to be careful about POSIX compatibility, you should avoid this usage.

The bash documentation also says the same thing about <& and >&, but without the promise of an error. Which is good, because it doesn't actually give an error. Instead, empirically n<&m and n>&m appear to be interchangeable. The only difference between <& and >& is that if you leave off the fd number on the left, <& defaults to 0 (stdin) and >& to 1 (stdout).

For example, let's start a shell with fd 1 pointing at a file bar, then try out exactly the exec 4<&1 example, try to write to the resulting fd 4, and see if it works:

$ sh -c 'exec 4<&1; echo foo >&4' >bar; cat bar
foo

It does, and this holds using either dash or bash (or bash --posix) for the shell.

Under the hood, this makes sense because <& and >& are almost certainly just calling dup2(), which doesn't care whether the fds are opened for reading or writing or appending or what.

[EDIT: Added reference to POSIX after discussion in comments.]

like image 50
Greg Price Avatar answered Sep 22 '22 06:09

Greg Price