重定向脚本中Windows批处理文件的输出



我试图使Windows批处理文件(主脚本)重定向它的所有输出到一个文件,同时仍然显示在屏幕上。我不能更改调用主脚本的所有代码-我需要更改主脚本本身。

我有一个解决方案需要"bootstrapping"通过从另一个bat文件(tee_start.bat)再次调用主脚本。我确信我想要避免的是重构所有调用main.bat的脚本来使用tee命令——如果我能在main.bat中添加一些新代码,这将是一个更小、更安全的更改。

是否有一种方法可以做到这一点,不涉及重新启动主文件,因为我正在做下面?例如,是否有一个cmd.exe或powershell.exe命令说"取我当前的STDOUT并查看它";-或者tee是否以某种方式支持这种行为,而我错过了它?或者,我是否应该满足于我已经实现的侵入性最小的方法?

我已经实现了一个解决方案如下:

main.bat

REM this is an example of bootstrap mode - it will restart this main script with all output logged
call tee_start.bat %~dpnx0 %*
echo This output should appear both in the screen console and in a log file

tee_start.bat

REM in order to bootstrap the output redirection - this script gets called twice - once to initialize logging with powershell tee command
REM second time, it just echoes log information and returns without doing anything
if x%LOG_FILE% neq x (
echo Bootstrapped Process: %1%
echo Escaped Arguments: %ADDL_ARGS%
echo Log File: %LOG_FILE%
goto :EOF
)
set ADDL_ARGS=
:loop_start
shift
if x%1 == x goto :after_loop
REM preserve argument structure (quoted or not) from the input
set ADDL_ARGS=%ADDL_ARGS% "%~1"
goto loop_start
:after_loop
SET LOG_FILE=/path/to/some/logfile.log
powershell "%1% %ADDL_ARGS% 2>&1 | tee -Append %LOG_FILE%"

我建议使用以下方法,它可以不使用aux。tee_start.bat文件:

main.batcontent(输出到当前文件夹的log.txt;根据需要调整):

@echo off & setlocal
if defined LOGFILE goto :DO_IT
set "LOGFILE=log.txt"
:: Reinvoke with teeing
"%~f0" %* 2>&1 | powershell -NoProfile -Command "$input | Tee-Object -FilePath "%LOGFILE%"; "[output captured in: %LOGFILE%]""
exit /b

:DO_IT
:: Sample output
echo [args: %*]
echo to stdout
echo to stderr >&2
echo [done]
  • Tee-Object使用固定字符编码,值得注意的是"Unicode"在Windows PowerShell (powershell.exe)和PowerShell (Core) 7+ (pwsh.exe)中(无bom - UTF-8)。

相关内容

最新更新