Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I'm reading a book about Linux command line where author doesn't seem to follow the conventions in bash manual regarding arrows symbols used in redirection operations. Namely, he always uses left arrow < in duplicating and closing file descriptors regardless of whether the descriptors are input or output ones.

Here is an example:

exec 3<&0 4<&1 #shouldn't be 4>&1 ?
#...
exec 3<&- 4<&- #shouldn't be 4>&- ?

Bash man page is vague in this point, according to it, the duplicating/closing and moving file descriptors have the following syntaxes:

#Duplicating and closing (in case word expands to -):
[n]<&word 
[n]>&word

#Moving:
[n]<&digit-
[n]>&digit-

They are described to have different behaviour only if we don't explicitly supply the n. But when we do, does it mean that we can use these forms interchangeably?

share|improve this question
1  
Shouldn"t it be 4>&1? Check linuxtopia.org/online_books/advanced_bash_scripting_guide/… –  ott-- Feb 16 '13 at 21:34
    
Right, my bad. However, the link doesn't answer my question... –  Quentin Feb 17 '13 at 0:42

1 Answer 1

up vote 2 down vote accepted

It doesn't matter because both 4>&1 and 4<&1 do the same thing: dup2(1, 4) which is the system call to duplicate a fd onto another. The duplicated fd automatically inherits the I/O direction of the original fd. (same for 4>&- vs 4<&- which both resolve to close(4), and 4>&1- which is the dup2(1, 4) followed by close(1)).

However, the 4<&1 syntax is confusing unless for some reason the fd 1 was explicitly open for reading (which would be even more confusing), so in my mind should be avoided.

The duplicated fd shares the same open file description which means they share the same offset in the file (for those file types where it makes sense) and same associated flags (I/O redirection/opening mode, O_APPEND and so on).

On Linux, there's another way to duplicate a fd (which is not really a duplication) and create a new open file description for the same resource but with possibly different flags.

exec 3> /dev/fd/4

While on Solaris and probably most other Unices, that is more or less equivalent to dup2(4, 3), on Linux, that opens the same resource as that pointed to by the fd 4 from scratch.

That is an important difference, because for instance, for a regular file, the offset of fd 3 will be 0 (the beginning of the file) and the file will be truncated (which is why for instance on Linux you need to write tee -a /dev/stderr instead of tee /dev/stderr).

And the I/O mode can be different.

Interestingly, if fd 4 pointed to the reading end of a pipe, then fd 3 now points to the writing end (/dev/fd/3 behaves like a named pipe):

$ echo a+a | { echo a-a > /dev/fd/0; tr a b; }
b+b
b-b

$ echo a+a | { echo a-a >&0; tr a b; }
bash: echo: write error: Bad file descriptor
b+b
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.