Aar*_*ron 5 windows cmd batch-file
这是一个说明我问题的最小例子:
:: test.bat
@echo off
call test2.bat 2>&1 | findstr foo
echo done calling test2
:: test2.bat
@echo off
start /B notepad >NUL
echo done starting child process
Run Code Online (Sandbox Code Playgroud)
在此示例中,在记事本关闭之前,findstr将无法完成,可能是因为记事本已从父cmd进程继承了stdout.如何修改test2.bat以便test.bat不挂起?
我相信我可以在没有任何批处理文件的情况下说明问题。只有在关闭 notepad.exe 后,以下管道构造才会完成:
start notepad | findstr "^"
Run Code Online (Sandbox Code Playgroud)
我希望记事本将在一个与 cmd.exe 管道完全分离的新进程中执行,并且唯一通过管道传输的内容是 START 命令本身的输出(没有)。START 命令“立即”返回,但只要记事本运行,管道就保持打开状态。
我不知道是否是继承的 I/O 流使管道保持打开状态,但我可以证明记事本进程正在以可能是问题根源的方式继承流。这基本上与Issue with output redirection in batch中提出的问题相同。
这是一个简单的批处理脚本:test.bat
@echo off
call :test >nul
echo done calling test.bat
exit /b
:test
start notepad
Run Code Online (Sandbox Code Playgroud)
请注意,当记事本启动时,由于 .stdout 的重定向,stdout 已被重定向到 NUL call :test >nul。
现在看看当我从命令行发出一系列命令时会发生什么,从 test.bat 开始,将 stdout 重定向到文件:
C:\test>test.bat >test.txt
C:\test>REM The command returns immediately, and notepad remains open
C:\test>type test.txt
done calling test.bat
C:\test>echo This fails as long as notepad remains open >test.txt
The process cannot access the file because it is being used by another process.
C:\test>type test.txt
done calling test.bat
C:\test>REM Now I close notepad
C:\test>echo This works once notepad is closed >test.txt
C:\test>type test.txt
This works once notepad is closed
C:\test>
Run Code Online (Sandbox Code Playgroud)
我至今仍对这种行为感到震惊。这似乎完全不合逻辑。
我认为没有任何方法可以阻止 cmd.exe 的流继承。
也许 Harry Johnston 的建议可以解决这个问题(来自问题评论):“我会编写一个非常简单的可执行文件来调用 CreateProcess 并禁用继承。”