Bash has several file descriptors used for input and ouptut.
- 1 is stdout
- 2 is stderr
- 3-9 can be used for other i/o (for example if you're using 1 to read from a file in a file loop, you can use 3 to read user input)
- 10+ is generally used by bash internally, though can be requested from bash if needed
Now for your examples, it's probably easier to view if you split the &
from the file descriptor. Both >&
and >&
are functionally equivalent and redirect from a given file descriptor to another. So in your examples:
The echo command will print whatever you give it to stdout (1), which in this case you redirect to stdout, so the redirection doesn't change anything.
$ echo "Hello" >& 1
The output of the echo command is redirected, and instead of going to stdout goes to stderr.
$ echo "Hello" >& 2
The output of the echo command is redirected, and instead of going to stdout bash tries to send it to file descriptor 3, however it hasn't been allocated yet, so bash throws an error.
$ echo "Hello" >& 3
You can allocate it to /dev/stdout for example, and then get the same result as your first redirection example.
$ exec 3<> /dev/stdout
$ echo "Hello" >& 3
Hello