wordpress   发布时间:2022-04-02  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了windows – 为什么我不能按顺序重定向到两个输入流`0 <`和`3 <`?大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

概述

当我尝试将多个文件重定向到多个流时,如下例所示,一切都按预期工作: 3< stream3.txt 4< stream4.txt echo/ 这样的东西也可以使用更多的流和文件以及除echo /甚至功能代码块之外的其他命令.即使使用保留的输出流1和2似乎也能正常工作. 但是,只要我按照给定的顺序使用以下流执行此操作: 0< stream0.txt 3< stream3.txt echo/ 托管命令提
当我尝试将多个文件重定向到多个流时,如下例所示,一切都按预期工作:
3< stream3.txt 4< stream4.txt echo/@H_301_2@ 
 

这样的东西也可以使用更多的流和文件以及除echo /甚至功能代码块之外的其他命令.即使使用保留的输出流1和2似乎也能正常工作.

但是,只要我按照给定的顺序使用以下流执行此操作:

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

托管命令提示符实例立即关闭.

当我更改流的顺序时,它再次正常工作:

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

那么,当我尝试按顺序输入重定向到流0和3时,为什么cmd实例意外终止?

我使用的是Windows 7(x64).

在我尝试执行上述失败的输入重定向之前,我用cmd打开一个新的命令提示符实例:

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

我可以读取出现的错误消息 – 假设文本文件包含其基本名称后跟换行符:

当我执行以下操作时,我可以看到两个文件实际上都被重定向

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

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

各自的输出

stream0@H_301_2@ 
 

和:

stream3@H_301_2@ 
 

这到底是怎么回事?

注意:这是对cmd内部发生的事情的简化
执行重定向命令.

让我们从指示的命令开始

0< file1  3< file2 echo/@H_301_2@ 
 

该命令被解析并在内存中创建所需重定向的表示,某种表/列表将保存有关重定向的信息:哪个句柄被重定向,旧保存的句柄,重定向时句柄应指向的位置,…

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

此时(解析命令后)没有更改流.

还有一个系统表,用于处理每个文件描述符(在我们的示例中为cmd流)确实指向的位置.

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

注意事实并非如此,底层结构有点复杂,但这样更容易看出它是如何工作的

当要执行该命令时,将调用内部SetRedir函数.它迭代先前的重定向请求表,保存现有句柄并创建所需的新句柄.最初的状态是

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

检索来自重定向请求表(R1)的第一个元素,将流0重定向到file1的请求.有必要保存当前句柄以便以后能够恢复它.对于此操作,使用_dup()功能.它将使用最小的可用文件描述符(上一个表中的流3)为传递的文件描述符(代码中的流0)创建别名.保存操作和旧手柄关闭后的情况是

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 |@H_301_2@ 
 

保存后,通过打开请求的文件完成重定向
文件描述符表中关联打开的文件句柄.在这种情况下
_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 |@H_301_2@ 
 

第一次重定向已经完成.现在是时候做同样的操作了
第二个.首先,使用_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  <<--/@H_301_2@ 
 

通过打开输入文件并将其与文件描述符相关联来完成重定向

_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@H_301_2@ 
 

重定向已完成,执行命令时,流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@H_301_2@ 
 

现在,使用第二个重定向完成相同的操作

_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 |         ---/@H_301_2@ 
 

一旦移除了重定向,& 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 !.!"@H_301_2@ 
 

这将产生

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:\>@H_301_2@ 
 

可以看出,在第一次测试中,set / p已从file2读取,并且在第二次测试中,尝试从& 3读取stdin流.

@H_450_119@

大佬总结

以上是大佬教程为你收集整理的windows – 为什么我不能按顺序重定向到两个输入流`0 <`和`3 <`?全部内容,希望文章能够帮你解决windows – 为什么我不能按顺序重定向到两个输入流`0 <`和`3 <`?所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。