RanRag
RanRag

Reputation: 49597

Bash: Explain the following the redirection cases

I am reading BashFAQ/002 and came accross the following redirection cases. I have written my understanding with each case so please comment if I am wrong.

Case 1

output=$(command 2>&1 >/dev/tty)

Redirect stderr to stdout and than redirect stdout to tty. So, now both stdout and stderr redirects/output to terminal.

Case 2

output=$(command 2>&1 >/dev/null)

Redirect stderr to stdout and than redirect stdout to /dev/null. Although I don't understand the point of doing this because now both stderr and stdout are discarded.

Case 3

output=$(command 3>&2 2>&1 1>&3-)

No, idea whatsoever whats happening here. I am not aware of fd 3.

Case 4

exec 3>&1 
output=$(command 2>&1 1>&3)
exec 3>&-

No, idea again.

So, can someone explain to me in detail the case#3 and case#4 and point me to the relevant documentation.

Upvotes: 0

Views: 174

Answers (3)

doubleDown
doubleDown

Reputation: 8408

2>&1 means you are duplicating stdout on stderr, i.e. you're redirecting stderr to where stdout is currently pointing at (let's simplify this by calling it "stdout's location").

This redirection is analogous to pass by value, and not pass by reference. So when you redirect stdout later, stderr does not get redirect too.

To illustrate, with output=$(command 2>&1 >/dev/tty)

  • 2>&1 redirects stderr to stdout's location.
  • >/dev/tty redirects stdout to /dev/tty, whereas stderr remains unchanged.

FDs 3-9 can be used however you want, e.g. to temporarily store other FD's location or to point at files.

In Case 3, FD3 is used to temporarily store stderr's location while stderr's location and stdout's location are being switched.

Note:

  • 1>&3- copies FD3's location to stderr, then closes FD3
  • 3>&- closes FD3

Case 4 is pretty much the same as Case 3. exec 3>&1 as used in Case 4 would have effect on all subsequent commands in the current shell (until closed with exec 3>&-), whereas the 3>&1 in Case 3 limits the redirection to command only.

Upvotes: 1

Mat
Mat

Reputation: 206929

Case 1 and 2 don't do what you describe. In both those cases, stderr will be redirected to whatever stdout was linked to before stdout is redirected. i.e. in both those cases, output will store whatever command printed to stderr, and stdout is redirected to /dev/tty and /dev/null respectively. (See also here, and the bash documentation here)

3 is just another file descriptor. There's nothing "magic" about it, the application/command/script define what it does.

For the forms with a - at the end, see the bash documentation under REDIRECTION and Moving File Descriptors, and A Detailed Introduction to I/O and I/O Redirection.

Upvotes: 2

mcalex
mcalex

Reputation: 6798

Sending data to /dev/null indicates you don't care about the result (for instance, you just wanted to perform the operation)

Case 3 & 4: Each open file gets assigned a file descriptor. The file descriptors for stdin, stdout, and stderr are 0, 1, and 2, respectively. For opening additional files, there remain descriptors 3 to 9. http://www.tldp.org/LDP/abs/html/io-redirection.html

Upvotes: 2

Related Questions