I think redirections are sorted for target handles in ascending order because Interpretation 1 should fail with duplication error when we try 1>&4.
So, interpretation 2 works when 1>&2 applied and then 1>&4 applied internally.
So, back to question which handle is written, it does not make any difference here because both target handles 2 and 4 are stderr. So, if there is a confusing situation like that how do we decide which handle is used to write output?
Code: Select all
(
echo Output42 1>&4 >&2
) | (echo # Running findstr & findstr /A:4E /N "^" )
Result - Nothing piped.
Output42
# Running findstr
echo Output42 1>&4 >&2
- Interpretation 1
- 1>&4
- 4 need to be duplicated to 1 but 1 is not empty.
- dup(1)->3(currently empty one), 3=stdout
- close(1), 1=nothing
- dup2(4,1), 1=4 ?? should cause duplication error !
- Interpretation 2
- 1>&2
- 2 need to be duplicated to 1 but 1 is not empty.
- dup(1)->3(currently empty one), 3=stdout
- close(1), 1=nothing
- dup2(2,1), 1=stderr(2 is stderr)
- 1>&4
- 4 need to be duplicated to 1 but 1 is not empty.
- dup(1)->4(currently empty one), 4=stderr
- close(1), 1=nothing
- dup2(4,1), 1=stderr(4 is stderr)
In the following only handle 1 is stdout and others are stderr. Redirections are about 2 and 3 but they are all piped so they are written to stdout, so, it seems applications only write to handle 1.
So, my question is confusing. It is not about redirection targets to decide what will be written to output. Thus, question must be; which handle applications use for writing to output? And it is handle 1.
Code: Select all
(
echo Output32 - no error and piped 3>&2
echo Output23 - no error and piped 2>&3
echo Output3223 - no error and piped 3>&2 2>&3
echo Output2332 - no error and piped 2>&3 3>&2
) | (echo # Running findstr & findstr /A:4E /N "^" )
# Result
# Running findstr
1:Output32 - no error and piped
2:Output23 - no error and piped
3:Output3223 - no error and piped
4:Output2332 - no error and piped
- Output32 is piped
- 3>&2
- 2 need to be duplicated to 3 and 3 is empty.
- dup2(2,3), 3=stderr(2 is stderr)
- Finally, 1=stdout, 2=3=stderr
- Output23 is piped
- 2>&3
- 3 need to be duplicated to 2 but 2 is not empty.
- dup(2)->3(currently empty one), 3=stderr
- close(2), 2=nothing
- dup2(3,2), 2=stderr(3 is stderr)
- Finally, 1=stdout, 2=3=stderr
- Output3223 is piped
- 3>&2
- 2 need to be duplicated to 3 and 3 is empty.
- dup2(2,3), 3=stderr(2 is stderr)
- 2>&3
- 3 need to be duplicated to 2 but 2 is not empty.
- dup(2)->4(currently empty one), 4=stderr
- close(2), 2=nothing
- dup2(3,2), 2=stderr(3 is stderr)
- Finally, 1=stdout, 2=3=4=stderr
- Output2332 is piped
- 2>&3
- 3 need to be duplicated to 2 but 2 is not empty.
- dup(2)->3(currently empty one), 3=stderr
- close(2), 2=nothing
- dup2(3,2), 2=stderr(3 is stderr)
- 3>&2
- 2 need to be duplicated to 3 but 3 is not empty.
- dup(2)->4(currently empty one), 4=stderr
- close(2), 2=nothing
- dup2(2,3), 2=stderr(3 is stderr)
- Finally, 1=stdout, 2=3=4=stderr
(It does not make any difference when we eliminate handle dependencies and run each echo solely.)
Code: Select all
(
echo Output4 - duplication error >&4
echo Output24 - duplication error >&2 >&4
echo Output42 - no error and nothing piped >&4 >&2
) | (echo # Running findstr & findstr /A:4E /N "^" )