What does "2<&1" redirect do in Bourne shell? What does "2<&1" redirect do in Bourne shell? shell shell

What does "2<&1" redirect do in Bourne shell?


The <& operator duplicates an “input” file descriptor. According to IEEE Std 1003.1-2001 (aka Single Unix Specification v3, the successor to POSIX), it's supposed to be an error to say 2<&1 if 1 is not a file descriptor open for input. However, it appears that bash is lazy and doesn't care if the file descriptor is open for input or for output.

So both 2<&1 and 2>&1 simply perform the system call dup2(1, 2), which copies file descriptor 1 to file descriptor 2.

You can check by running a command like this, since redirections are performed left-to-right:

sleep 99999 1>/dev/null 2<&1

Then in another window, run lsof on the sleep process. You'll see that both file descriptors 1 and 2 point to /dev/null. Example (on my Mac):

:; ps axww | grep sleep 8871 s001  R+     0:00.01 grep sleep 8869 s003  S+     0:00.01 sleep 99999:; lsof -p 8869 | tail -2sleep   8869 mayoff    1w   CHR    3,2       0t0       316 /dev/nullsleep   8869 mayoff    2w   CHR    3,2       0t0       316 /dev/null


Looking at the parser code in the source for Bash, it seems that 2>&1 is treated in the same way as 2<&1.

parse.y

|   NUMBER LESS_AND NUMBER        {          redir.dest = $3;          $$ = make_redirection ($1, r_duplicating_input, redir);        }...|   NUMBER GREATER_AND NUMBER        {          redir.dest = $3;          $$ = make_redirection ($1, r_duplicating_output, redir);        }

Looking through the redirection source redir.c, the constants r_duplicating_input and r_duplicating_output seem to be treated in the same way. Same as in the make_redirection function in make_cmd.c.

Testing with a simple program that prints "yay" to stdout and "nay" to stderr, I can confirm your test results:

$ ./a.out > out 2>&1$ cat outnayyay$ ./a.out > out 2<&1$ cat outnayyay$ ./a.out > out 1>&2yaynay$ cat out$ ./a.out > out 1<&2yaynay$ cat out$


From man bash under REDIRECTION:

   Duplicating File Descriptors       The redirection operator              [n]<&word       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  descrip‐       tor.   If  the  digits  in  word  do  not  specify a file       descriptor open for input, a  redirection  error  occurs.       If  word evaluates to -, file descriptor n is closed.  If       n is not specified, the standard input  (file  descriptor       0) is used.

So in the case of 2<&1, it seems that 2 (stderr) is made to be a copy of 1 (stdout). I've tested it with the other way around 1<&2 makes stdout to be a copy of stderr.

So in a test program:

#!/bin/bashecho hello 1<&2

When run on command line, hello is output to stderr not stdout

$ ./test > /dev/nullhello$ ./test > /dev/null 2>&1$