Early in a script, I see this:
exec 3>&2
And later:
{ $app $conf_file &>$app_log_file & } 1>&3 2>&1
My understanding of this looks something like this:
- Create fd
3
- Redirect fd
3
output tostderr
- (Upon app execution) redirect
stdout
to fd3
, then redirectstderr
tostdout
Isn’t that some kind of circular madness? 3
>stderr
>stdout
>3
>etc?
I’m especially concerned as to the intention/implications of this line because I’d like to start running some apps using this script with valgrind
. I’d like to see valgrind
‘s output interspersed with the app’s log statements, so I’m hoping that the default output of stderr
is captured by the confusing line above. However, in some of the crashes that have led me to wanting to use valgrind
, I’ve seen glibc errors outputted straight to the terminal, rather than captured in the app’s log file.
So, the question(s): What does that execution line do, exactly? Does it capture stderr
? If so, why do I see glibc output on the command line when an app crashes? If not, how should I change it to accomplish this goal?
Advertisement
Answer
You misread the 3>&2
syntax. It means open fd 3 and make it a duplicate of fd 2. See Duplicating File Descriptors.
In the same way 2>&1
does not mean make fd 2 point to the location of fd 1 it means re-open fd 2 as a duplicate of fd 1 (mostly the same net effect but different semantics).
Also remember that all redirections occur as they happen and that there are no “pointers” here. So 2>&1 1>/dev/null
does not redirect standard error to /dev/null
it leaves standard error attached to wherever standard output had been attached to (probably the terminal).
So the code in question does this:
- Open fd 3 as a duplicate of fd 2
- Re-open fd 1 as a duplicate of fd 3
- Re-open fd 2 as a duplicate of fd 1
Effectively those lines send everything to standard error (or wherever fd 2 was attached when the initial exec
line ran). If the redirections had been 2>&1 1>&3
then they would have swapped locations. I wonder if that was the original intention of that line since, as written, it is fairly pointless.
Not to mention that with the redirection inside the brace list the redirections on the outside of the brace list are fairly useless.