Page 1 of 1

Which handle is written to stdout?

Posted: 18 Jul 2020 05:18
by lockedscope
- 1. In the following, how do we decide which handle is written to stdout, handle 2 or handle 4? :?:

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)
- :idea: 1. Question answer: I think i understand what is happening with following samples;
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

- 2. Another question is contrary to the handle sorting theory above, when we write 2 before 4 (>&2 >&4) it fails with duplication error. So, there is a conundrum i don't understand, i am missing some point here... :?:
(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 "^" ) 


- :idea: 2. question answer: I think i understand what is happening; redirections are grouped by source handles and only the last redirection for each source handle is taken into account. I realized when i turned on echo to see what is happening. So, Output4 and Output24 redirects to undefined stream 4 and causes duplication error and Output42 redirects to stream 2 so writes to stderr.