Tuesday, 20 November 2007

bash redirection (what "duplication" of file descriptor really means and how to use it.

This has annoyed me for YEARS! Much reading of `man bash` and the internet didn't come up with a solution until yesterday.


# save stderr and stdout to seperate files AND show to user
bash$ ((ls gah source/ 2>&1 1>&3 | tee stderr.log) 3>&1 1>&2 | tee stdout.log) 2>&1

Anyway 2>&1 syntax is "duplicating" stderr to stdout. But this sense of "duplicate" has not made sense to be before because in doing 2>&1 then stderr is ONLY going to stdout and not to stderr anymore. BUT using the ()s => AHHH! that's where stderr and stdout are duplicated.


( (ls gah source/ 2>&1 1>&3 | tee stderr.log) 3>&1 1>&2 | tee stdout.log ) 2>&1
(dup stderr(2) to stdout(1) and stdout(1) to fd3 |tee stores what's on stdout (now stderr))
now outside inner ()s
stderr is on fd1, stdout is on fd3, nothing is on fd2
try this: (ls gah . 2>&1 1>&3 |tee stderr.log) 3>fd3 2>fd2 1>fd1
( dup fd3(original stdout) back to stdout(1), dup fd1(original stderr) back to stderr(2)
|tee stores what's on stdout (now original stdout))
now outside all ()s
stdout is on fd1, stderr is on fd2 as originally

All is clear as semi-translucent puddle-water ?

And I'd to look up how to acheive parameter expansion in bash parameter name AGAIN. Using ! is not intuitive.


bash redirect stderr stdout

No comments: