英文:
Redirect output from a Windows batch file within the script
问题
我正在尝试创建一个Windows批处理文件(主脚本),将其所有输出重定向到文件,同时仍然在屏幕上显示输出。我不能更改调用主脚本的所有代码 - 我需要更改主脚本本身。
我有一个解决方案,需要通过从另一个批处理文件(tee_start.bat)再次调用主脚本来进行“引导”。
我确定我要避免的是重构调用main.bat的所有其他脚本以使用tee命令 - 如果我可以在main.bat中放置一些新代码,那将是一个更小、更安全的更改。
是否有一种方法可以做到这一点,而不涉及像我下面所做的重新启动主文件?
例如,是否有一个cmd.exe或powershell.exe命令可以说“接管我的当前标准输出并将其tee出来” - 或者tee是否以某种方式支持此行为,而我错过了它?
或者,作为替代方案,我应该满足于我已经实施的最不侵入性的方法?
我已经实施了一个解决方案如下:
main.bat
REM 这是引导模式的示例 - 它将重新启动此主脚本,并记录所有输出
call tee_start.bat %~dpnx0 %*
echo 此输出应同时出现在屏幕控制台和日志文件中
tee_start.bat
REM 为了引导输出重定向 - 此脚本被调用两次 - 一次用powershell tee命令初始化日志记录
REM 第二次,它只是回显日志信息并返回而不执行任何操作
if x%LOG_FILE% neq x (
echo 引导过程:%1%
echo 转义参数:%ADDL_ARGS%
echo 日志文件:%LOG_FILE%
goto :EOF
)
set ADDL_ARGS=
:loop_start
shift
if x%1 == x goto :after_loop
REM 保留输入中的参数结构(带引号或不带引号)
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%"
英文:
I am trying to make a Windows batch file (the main script) redirect all of it's output to a file while still displaying it on the screen. I cannot change all the code that calls the main script - I need to change the main script itself.
I have a solution that requires "bootstrapping" the main script by calling it again from another bat file (tee_start.bat).
What I'm sure I want to avoid is refactoring all the other scripts that call main.bat to use the tee command - it will be a much smaller, safer change if I can put some new code in main.bat.
Is there a way to do this that does not involve restarting the main file as I am doing below?
For example, is there a cmd.exe or powershell.exe command that says "Take my current STDOUT and tee it" - or does tee somehow support this behavior and I missed it?
Or, alternatively, should I settle for what I have implemented as the least invasive method?
I have implemented a solution as follows:
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%"
答案1
得分: 4
以下是翻译好的部分:
<!-- language-all: sh -->
我建议采用以下方法,无需辅助的 `tee_start.bat` 文件:
`main.bat` 内容(将输出到当前文件夹中的 `log.txt`;根据需要进行调整):
@echo off & setlocal
if defined LOGFILE goto :DO_IT
set "LOGFILE=log.txt"
:: 使用重定向重新调用
"%~f0" %* 2>&1 | powershell -NoProfile -Command "$input | Tee-Object -FilePath \"%LOGFILE%\"; \"[output captured in: %LOGFILE%]\""
exit /b
:DO_IT
:: 示例输出
echo [args: %*]
echo 输出到标准输出
echo 输出到标准错误 >&2
echo [完成]
Tee-Object
使用固定的字符编码,在 Windows PowerShell(powershell.exe
)中是“Unicode”(UTF-16LE),在 PowerShell(Core)7+(pwsh.exe
)中是(无BOM的UTF-8)。
<details>
<summary>英文:</summary>
<!-- language-all: sh -->
I suggest the following approach, which makes do without the aux. `tee_start.bat` file:
`main.bat` content (outputs to `log.txt` in the current folder; adjust as needed):
@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`](https://learn.microsoft.com/powershell/module/microsoft.powershell.utility/tee-object) uses a _fixed_ character encoding, which is notably "Unicode" (UTF-16LE) in Windows PowerShell ([`powershell.exe`](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_powershell_exe)), and (BOM-less UTF-8) in PowerShell (Core) 7+ ([`pwsh.exe`](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_pwsh)).
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论