Windows批处理或PowerShell中适配管道的/dev/stdout等效文件名
问题原因
你遇到的问题核心是Windows的特殊设备名con和Linux的/dev/tty行为一致,会直接绑定当前活动控制台的输入输出缓冲区,完全绕过管道、重定向规则,所以下游的cmd2收不到任何数据。Windows原生没有和/dev/stdout完全同名的设备文件,可以根据你用的cmd1程序类型,选择下面的方案实现等效效果。
可用方案
优先方案:使用
-作为特殊输出路径绝大多数从Linux移植到Windows的命令行工具(比如GNUWin32、MSYS2、Git for Windows、Cygwin提供的工具),都遵循Unix工具的通用约定:把
-作为标准输入/输出的特殊文件名。直接把-o的参数改成-即可,管道可以正常工作,批处理和PowerShell下写法通用::: 批处理写法 cmd1 -o - | cmd2# PowerShell写法 cmd1 -o - | cmd2如果cmd1支持不传递
-o参数时默认输出到标准流,直接省略-o参数即可,这是兼容性最好的写法:cmd1 | cmd2原生Windows程序方案:使用
CONOUT$设备名如果cmd1是原生Windows程序,不识别
-特殊文件名,可以传CONOUT$作为输出路径。这个是Windows内核提供的特殊设备名,指向当前进程绑定的标准输出句柄,在管道、重定向场景下不会绕开流规则,数据可以正常传给下游的cmd2::: 批处理写法 cmd1 -o CONOUT$ | cmd2# PowerShell写法 cmd1 -o CONOUT$ | cmd2注意:不要给
CONOUT$加任何路径前缀,直接传纯文件名即可;绝对不要用con,这个设备始终直连物理控制台,会导致管道失效。兜底兼容方案:临时文件中转
如果遇到极少数程序既不识别
-,也无法正常写入CONOUT$,可以用临时文件做中转,兼容性100%,只是会多一次磁盘读写:
批处理版本:@echo off set "TMP_OUT=%temp%\cmd1_out_%random%.tmp" cmd1 -o "%TMP_OUT%" type "%TMP_OUT%" | cmd2 del /f /q "%TMP_OUT%"PowerShell版本:
$tmpOut = New-TemporaryFile cmd1 -o $tmpOut.FullName Get-Content $tmpOut.FullName | cmd2 Remove-Item $tmpOut.FullName -Force
内容的提问来源于stack exchange,提问作者Joseph Sible-Reinstate Monica
相关产品推荐
相关产品推荐

