Why can't I redirect to two input streams `0 <` and `3 <` in this order?

When I try to redirect multiple files to multiple threads, as in the following example, everything works as expected:

3< stream3.txt 4< stream4.txt echo/

Something like this also works with more threads and files and other commands than echo/or even a functional block of code. Even using reserved output streams, 1they 2work just fine.

However, as soon as I do this with the following threads in the given order:

0< stream0.txt 3< stream3.txt echo/

The hosting command line screen closes immediately.

When I reorder the threads, it works fine again:

3< stream3.txt 0< stream0.txt echo/

, cmd - 0 3 ?

Windows 7 (x64).


cmd, :

cmd
0< stream0.txt 3< stream3.txt echo/

- , , :

'stream3' is not recognised as an internal or external command, operable program or batch file.

, , :

cmd /V
0< stream0.txt 3< stream3.txt (set /P #="" & echo/!#!)

cmd /V
0< stream0.txt 3< stream3.txt (<&3 set /P #="" & echo/!#!)

:

stream0

stream3

, , ?

+6
2

note. , cmd, .

0< file1  3< file2 echo/

, , - /, : , , ,...

    Redirection requests
   ------------------------------- 
    redirect   saved   redirectTo
   +--------+--------+------------
R1 | 0                 file1
   |
R2 | 3                 file2

( ) .

, ( cmd).

    File descriptors
   ------------------  
    points to
   +----------------- 
 0 | stdin
 1 | stdout
 2 | stderr
 3 |
 4 |

note , , , .

, SetRedir. , .

    Redirection requests                         File descriptors
   -------------------------------              ------------------
    redirect   saved   redirectTo                points to
   +--------+--------+------------              +-----------------
R1 | 0                 file1                  0 | stdin
   |                                          1 | stdout
R2 | 3                 file2                  2 | stderr
                                              3 |
                                              4 |

(R1), 0 1. , . _dup(). ( 0 ), ( 3 ).

   R1[saved] = _dup( R1[redirect] );
   _close( R1[redirect] );

    Redirection requests                         File descriptors
   -------------------------------              ------------------
    redirect   saved   redirectTo                points to
   +--------+--------+------------              +-----------------
R1 | 0        3        file1                  0 |          ---\
   |                                          1 | stdout      | 
R2 | 3                 file2                  2 | stderr      |
                                              3 | stdin   <<--/
                                              4 |

. _dup2()

 _dup2( CreateFile( R1[redirectTo] ), R1[redirect] );

    Redirection requests                         File descriptors
   -------------------------------              ------------------
    redirect   saved   redirectTo                points to
   +--------+--------+------------              +-----------------
R1 | 0        3        file1                  0 | file1   <<---
   |                                          1 | stdout
R2 | 3                 file2                  2 | stderr
                                              3 | stdin 
                                              4 |

. . _dup(). (3) (4)

   R2[saved] = _dup( R2[redirect] );
   _close( R2[redirect] );

    Redirection requests                         File descriptors
   -------------------------------              ------------------
    redirect   saved   redirectTo                points to
   +--------+--------+------------              +-----------------
R1 | 0        3        file1                  0 | file1
   |                                          1 | stdout
R2 | 3        4        file2                  2 | stderr
                                              3 |         ---\
                                              4 | stdin  <<--/

,

_dup2( CreateFile( R2[redirectTo] ), R2[redirect] );

    Redirection requests                         File descriptors
   -------------------------------              ------------------
    redirect   saved   redirectTo                points to
   +--------+--------+------------              +-----------------
R1 | 0        3        file1                  0 | file1
   |                                          1 | stdout
R2 | 3        4        file2                  2 | stderr
                                              3 | file2  <<---
                                              4 | stdin

, 0, file1, 3 file2.

, . ResetRedir() . _dup2() . .

_dup2( R1[saved], R1[redirect] );
R1[saved] = null;

    Redirection requests                         File descriptors
   -------------------------------              ------------------
    redirect   saved   redirectTo                points to
   +--------+--------+------------              +-----------------
R1 | 0                 file1                  0 | file2  <<--\
   |                                          1 | stdout     |
R2 | 3        4        file2                  2 | stderr     |
                                              3 |         ---/
                                              4 | stdin

_dup2( R2[saved], R2[redirect] );
R2[saved] = null;

    Redirection requests                         File descriptors
   -------------------------------              ------------------
    redirect   saved   redirectTo                points to
   +--------+--------+------------              +-----------------
R1 | 0                 file1                  0 | file2
   |                                          1 | stdout
R2 | 3                 file2                  2 | stderr
                                              3 | stdin  <<--\
                                              4 |         ---/

, &0 file2, stdin &3.

@echo off
    setlocal enableextensions disabledelayedexpansion

    >file1 echo This is file 1
    >file2 echo This is file 2

    echo Test 1 - trying to read from stdin after redirection
    cmd /v /c"( 0< file1 3< file2 echo - test1 ) &     set /p .=prompt & echo !.!"

    echo(
    echo(

    echo Test 2 - trying to read from stream 3 after redirection
    cmd /v /c"( 0< file1 3< file2 echo - test 2 ) & <&3 set /p .=prompt & echo !.!"

W:\>testRedirection.cmd
Test 1 - trying to read from stdin after redirection
- test1
prompt This is file 2


Test 2 - trying to read from stream 3 after redirection
- test 2
prompt This is typed text
This is typed text

W:\>

, set /p file2, , &3, stdin .

+4

, . :

0< stream0.txt 3< stream3.txt findstr .

findstr .

<CON pause

findstr stream0.txt, .

findstr stream3.txt, , 0 .

, , , , , .


MC ND, , 3. test7.cmd:

0< stream0.txt 4< stream3.txt findstr .

findstr .

:done
<CON pause

cmd /c test7 cmd /c test7 3< other.txt , cmd /c "test7 3< other.txt". ( facepalm, , . , , script.)

, " 3, 0", " , 0".: -)

+3

Source: https://habr.com/ru/post/1015162/


All Articles