批处理For循环中PowerShell EncodedCommand的STDERR输出异常问题
批处理For循环调用PowerShell EncodedCommand时STDERR输出异常及字符限制问题
在批处理的For循环中调用PowerShell EncodedCommand时,若使用[Console]::Error.WriteLine强制输出内容到STDERR,所有STDERR文本会提前一次性全部显示,后续的功能/进程必须等STDERR输出完全结束后才会实际执行。
实际验证发现:所有可见输出显示后,PowerShell EncodedCommand看似处于挂起状态,但查看日志文件能看到,本该同步执行的代码其实是在STDERR输出完成后才运行;即使把STDERR输出到日志也能证实,所有STDERR内容在实际进程完成前就已经处理完毕。这是批处理For循环拦截PowerShell命令输出的标准行为吗?有没有遗漏的细节?
技术代码示例
PowerShell脚本(已转为EncodedCommand)
Function Write_Log { Param([string]$textOut) write-Host $textOut; write-Output $textOut | Out-File -FilePath ("$Env:log" -replace '"','') -Append -Encoding default } # 此函数引发异常现象,无报错 Function Write_StdErr { Param([string]$textOut) If ([int]$Env:isGiveStatus) {Clear-Host; [Console]::Error.WriteLine($textOut); Start-Sleep -Milliseconds 250 } } For ($i=1; $i -le 100; $i++) { # 该行不会被批处理For循环解析,仅向用户显示 Write_StdErr "Checking for Object [$i] Values" # 执行操作 # 该行会被批处理For循环解析,不向用户显示 Write_Log "Current Object being checked: [$i]" $true # 执行更多操作 } Exit 0
批处理脚本片段
set "isGiveStatus=1" & REM 确保Write_StdErr函数输出内容 REM 此For循环从PowerShell的STDOUT输出中提取数据到变量 REM PowerShell中的Write_StdErr函数用于绕过For循环处理,直接向用户显示文本 for /f "Tokens=2 Delims=[]" %%A in ('Powershell -NoProfile -ExecutionPolicy Bypass -EncodedCommand !newEncodeCMD!') do ( cls ping 127.0.0.1 -n 1 >nul ping 127.0.0.1 -n 1 >nul ping 127.0.0.1 -n 1 >nul If "%~7"=="CustomFunc" ( If "%%~A"=="" ( Call :WriteOut "The parameter from the PowerShell Script was empty." %log% "Yes" ) else ( REM 批处理子例程作为第8个参数传入,如":SubRoutineName" Call %~8 "%%~A" REM 注意:调用的例程不向控制台输出内容,仅记录到日志文件 set "Powershell_Rslt=!errorlevel!" ) ) else ( set "Powershell_Rslt=!errorlevel!" REM Echo %%A set "%~8=%%A" ) )
编辑补充
尝试Aacini的方法后基本有效,但遇到了set /p的1023字符限制问题,循环始终在第6次迭代时停止,希望找到突破该限制的解决方案。
内容的提问来源于stack exchange,提问作者k1dfr0std
相关产品推荐
相关产品推荐

