windows - 为什么 XCOPY/W 和 REPLACE/W 为它们的单字符提示消耗所有重定向的文本数据?

标签 windows batch-file cmd io-redirection xcopy

当有文本文件时 test.txt包含这个1:

test
data

以下代码返回删除第一个字符的文本文件的内容:

< "test.txt" (
    > nul pause
    findstr "^"
)

使用管道时也会发生同样的情况:

type "test.txt" | (
    > nul pause
    findstr "^"
)

因为 pause命令只需要一个字符。

但是,当替换 pause 时通过以下任一命令执行命令,输出为空,尽管 - 类似于 pause – 他们仅提示 ( /W ) 单个字符:

  • 2> nul xcopy /W ? .
  • replace /W /U ? .

这是为什么,这里发生了什么?
xcopy /Wreplace /W消耗所有重定向/管道文本数据,甚至多行,尽管它们只显示它们收到的第一个字符?他们在乱弄文件指针吗?
有没有办法防止这些命令吸收多个字符?


1 ... 最后一行以换行符终止 findstr不要无限期地挂起 – 请参阅此线程:What are the undocumented features and limitations of the Windows FINDSTR command? , 如果重定向的输入不以 <LF> 结尾,则 FINDSTR 部分将在 XP 和 Windows 7 上挂起«.

最佳答案

重定向与管道之间的行为实际上有所不同。

重定向

看起来 XCOPY 和 REPLACE 只是将标准输入文件指针移动到文件结尾 (EOF)。

如果您使用 FIND/V "" 而不是 FINDSTR "^",那么您会得到整个文件作为输出,因为 FIND 将文件指针重置为启动时的文件。所以XCOPY运行后stdin流仍然有效,但是文件指针在EOF。

XCOPY 必须在没有实际读取所有数据的情况下移动文件指针,因为当我使用包含 0.5 GBytes 的 big.txt 时,它仍然是“即时的”。如果 XCOPY 在继续之前必须读取所有文件,将会有明显的延迟。

管道

我不完全理解这意味着什么,但我相信标准管道是 block 缓冲的。 XCOPY 和 REPLACE 在继续之前最多读取 1 个完整 block ,将剩余的管道数据留给 FINDSTR 读取。

我输入了一个包含 4191 个字节的 127 行文件,FINDSTR 在 3 行中输出了 97 个字节。所以在这种情况下,XCOPY 似乎读取了 4094 个字节。

然后我在一个没有任何新行的 5000 字节文件中通过管道传输,FINDSTR 输出 908 字节,这意味着 XCOPY 似乎读取 4092 字节。

所以管道 block 缓冲区必须在 4 kbytes 附近的某个地方。我的猜测是 XCOPY 只是将文件指针移动到当前缓冲区的末尾而不读取所有数据,但我不知道如何测试它。

正如预期的那样,在使用管道时用 FIND 代替 FINDSTR 不会改变结果 - 在读取数据后无法将文件指针重置回管道数据的开头。


我无法想象有任何方法可以修改 XCOPY 或 REPLACE 的行为...它就是这样。

至于为什么 XCOPY 和 REPLACE 的行为方式是这样的?......我没有任何线索。 Microsoft 的“批处理”世界是如此奇特,以至于我很久以前就放弃了问为什么。

关于windows - 为什么 XCOPY/W 和 REPLACE/W 为它们的单字符提示消耗所有重定向的文本数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50242800/

相关文章:

Windows 批处理脚本复制最近 x 分钟内修改的文件

c - 如何为 Xeon Phi 编译 C 代码 (Windows 10)

windows - 什么脚本(比如 .bat)可以在 windows、mac 和 linux 上运行

c# - 使用 C# 执行命令行

windows - 从 Windows 服务启动应用程序

windows - Emacs 打开 Windows 网络登录提示

batch-file - 通过子目录将.wav文件批量转换为.mp3文件,然后删除其余的.wav文件

windows - 如何从批处理文件调用Powershell文件

windows - 如何更改 Windows 源代码树中的默认终端

powershell - 使用批处理脚本删除csv文件的第一行和最后一行