Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash: multiple redirection

Tags:

linux

bash

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 to stderr
  • (Upon app execution) redirect stdout to fd 3, then redirect stderr to stdout

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?

like image 507
pdm Avatar asked Jul 08 '15 18:07

pdm


People also ask

What is redirect in Bash command line?

Redirect operators are a basic but essential part of working at the Bash command line. See how to safely redirect input and output to make your Linux sysadmin life easier. Posted: January 22, 2021 | Damon Garn (Red Hat)

How do I redirect CMD output to two files?

To redirect the output from cmd to two files, but not to the console, you can use: This will work for multiple files, given any data source piping to tee: Without the /dev/null redirection, tee will send output to stdout in addition to the files specified.

How are redirects processed in Linux?

Redirections are processed in the order they appear, from left to right. Each redirection that may be preceded by a file descriptor number may instead be preceded by a word of the form { varname }. In this case, for each redirection operator except >&- and <&-, the shell will allocate a file descriptor greater than 10 and assign it to { varname }.

How do I redirect stdout to a file in Linux?

From bash 4.4, you can also use &> sign to redirect both stdout and stderr to a file. What is /dev/null? Null is a character special file that accepts input and discards the input and produces no output. To put this simply, null discards whatever you redirect to it.


1 Answers

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:

  1. Open fd 3 as a duplicate of fd 2
  2. Re-open fd 1 as a duplicate of fd 3
  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.

like image 179
Etan Reisner Avatar answered Oct 05 '22 20:10

Etan Reisner