I understand that exec can do I/O redirection on the current shell, but I only sees usage like:

exec 6<&0   # Link file descriptor #6 with stdin.
            # Saves stdin.

exec 6>&1   # Link file descriptor #6 with stdout.
            # Saves stdout.

From that I understand that < is for input stream, > is for output stream. So what does exec 3<&1 do?

PS: I found this from Bats source code

  • @Gnouc is obviously correct, but it should be noted that exec 3<&1 differs from 3<&1 in that the latter will affect a single command whereas the former affects the current shell. – mikeserv Mar 20 '14 at 7:37

From bash manpage:

Duplicating File Descriptors
       The redirection operator


       is used to duplicate input file descriptors.  If word expands to one or
       more  digits,  the file descriptor denoted by n is made to be a copy of
       that file descriptor.  If the digits in word  do  not  specify  a  file
       descriptor  open for input, a redirection error occurs.  If word evalu‐
       ates to -, file descriptor n is closed.  If n  is  not  specified,  the
       standard input (file descriptor 0) is used.

       The operator


       is  used  similarly  to duplicate output file descriptors.  If n is not
       specified, the standard output (file descriptor 1)  is  used.   If  the
       digits  in word do not specify a file descriptor open for output, a re‐
       direction error occurs.  As a special case, if n is omitted,  and  word
       does not expand to one or more digits, the standard output and standard
       error are redirected as described previously.

I did some debugs with strace:

sudo strace -f -s 200 -e trace=dup2 bash redirect.sh

For 3<&1:

dup2(3, 255)                            = 255
dup2(1, 3)                              = 3

For 3>&1:

dup2(1, 3)                              = 3

For 2>&1:

dup2(1, 2)                              = 2

It seems that 3<&1 do exactly the same as 3>&1, duplicating stdout to file descriptor 3.

| improve this answer | |
  • From the manpage, I would expect it to throw a redirection error because stdout is not open for input. However, it really does duplicate stdin (which is &0). How? – orion Mar 20 '14 at 7:05
  • 2
    @orion: Internally, the same dup2() syscall is used for any kind of file descriptor; bash's x>&y vs x<&y is just syntax sugar. Also, when stdio is attached to a tty, the tty device is very often opened for read+write and just duplicated from 0 to 1 and 2. – user1686 Mar 20 '14 at 7:13
  • @grawity so exec 3<&1 is same as exec >&3 ? – Zhenkai Mar 20 '14 at 7:17
  • No, but it is the same as exec 3>&1. – user1686 Mar 20 '14 at 7:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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