我正在尝试制作一个 Windows 批处理文件(主脚本)将其所有输出重定向到一个文件,同时仍将其显示在屏幕上。我无法更改调用主脚本的所有代码 - 我需要更改主脚本本身。
我有一个解决方案,需要通过从另一个bat文件(tee_start.bat)再次调用它来“引导”主脚本。 我确信我想要避免的是重构所有其他调用 main.bat 的脚本以使用 tee 命令 - 如果我可以在 main.bat 中放入一些新代码,这将是一个更小、更安全的更改。
有没有一种方法可以做到这一点,而不需要像我下面所做的那样重新启动主文件? 例如,是否有一个 cmd.exe 或 powershell.exe 命令说“获取我当前的 STDOUT 并发球” - 或者发球是否以某种方式支持此行为而我错过了? 或者,我应该满足于我所实现的侵入性最小的方法吗?
我实现了如下解决方案:
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%"
最佳答案
我建议采用以下方法,无需辅助即可解决。 tee_start.bat
文件:
main.bat
内容(输出到当前文件夹中的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
使用固定字符编码,尤其是 Windows PowerShell 中的“Unicode”(UTF-16LE) (powershell.exe
),以及 PowerShell (Core) 7+ 中的(BOM-less UTF-8)(pwsh.exe
)。
关于windows - 重定向脚本内 Windows 批处理文件的输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75050918/