views:

56

answers:

4
A: 

3.Nope. The ordering matters, so it gets rid of the original stdout, then it moves stderr to stdout.

4.3 is just another file descriptor, same as the first 3. Most processes can use a total of 256 different file descriptors.

Ignacio Vazquez-Abrams
Lazer
Redirections are effected right-to-left.
Ignacio Vazquez-Abrams
@Ignacio: Then how does it work in **4**? That would mean stream 3 is closed even before it was opened!
Lazer
That just means that whatever *may* have been open on it has been closed.
Ignacio Vazquez-Abrams
Lazer
FD 2 gets copied to FD 3. 2 doesn't point nowhere, 3 now points where 2 does.
Ignacio Vazquez-Abrams
@Ignacio: your understanding is wrong, please don't confuse people. From http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_07: "If more than one redirection operator is specified with a command, the order of evaluation is from beginning to end."
Roman Cheplyaka
Roman Cheplyaka
A: 

Though documented in the perldocs, the redirection is all standard linux redirection. You understand 1 and 2 correctly.

3) Only STDOUT is normally caught by a basic redirect (>), so the original STDOUT must be discarded, and STDERR must be send to STDOUT.

4) cmd 3>&1 1>&2 2>&3 3>&- is equivalent to

var tmp = STDOUT;
STDOUT = STDERR;
STDERR = tmp;
delete tmp;
bemace
+2  A: 

Really, none of this is Perl -- all of this is handled by the shell that you're invoking by using the backticks operator. So your best reading is man sh, or the Shell chapter of the Unix standard.

In short, though, for #4:

  • 3>&1: Open FD 3 to point to where stdout currently points.
  • 1>&2: Reopen stdout to point to where stderr currently points.
  • 2>&3: Reopen stderr to point to where FD 3 currently points, which is where stdout pointed before the previous step was completed. Now stdout and stderr have been succesfully swapped.
  • 3>&-: Close FD 3 because it's not needed anymore.
hobbs
@hobbs: redirections are affected left to right, are they?
Lazer
@Lazer: that's correct.
Roman Cheplyaka
@Lazer yes they are. The standard says as much too. :)
hobbs
+1  A: 

Normally we have this:

1-->STDOUT
2-->STDERR

2>&1 redirects file descriptor fd2 to fd1

1-->STDOUT
   /
2./

2>/dev/null redirects fd2 to /dev/null.

1-->STDOUT
2-->/dev/null

2>&1 1>/dev/null redirects fd2 to fd1, and then redirects fd1 to /dev/null

    /dev/null
   /
1./ STDOUT
   /
2./

3>&1 1>&2 2>&3 3>&-

  1. first directs a new fd 3 to wherever fd 1 is currently pointing (STDOUT).
  2. then redirects fd1 to wherever fd2 is current pointing (STDERR),
  3. then redirects fd 2 to wherever fd 3 is currently pointing (STDOUT)
  4. then closes fd3 (3>&- means close file descriptor 3).

The whole thing effectively swaps fd1 and fd2. fd3 acted as a temporary variable.

1 --STDOUT
 X
2 `-STDERR

See the docs for more information on IO redirection.

unutbu